Saltar al contenido
Development

Enviar una función de un paquete compartido a través de dos repos para una sola ruta

Por Victor Da Luz
astrorssdev-logastro-tools

El pedido era chico en el papel: agregar un feed RSS. Un spike ya lo había marcado como el vacío de mayor valor en el sitio, y el arreglo parecía un archivo de quince líneas, filtrar la colección del blog por fecha de publicación, pasársela a @astrojs/rss, listo.

Después surgió una pregunta que el issue no había hecho: ¿esto debería vivir en el paquete de componentes compartido en vez de solo en este sitio? Tanto imperfectsystems.com como vdaluz.com toman de @vdaluz/astro-blog, el mismo paquete, y vdaluz.com tampoco tiene feed RSS. Acotar el arreglo a un solo repo significaba que el segundo sitio enfrentaría exactamente las mismas quince líneas más adelante, probablemente copiadas y pegadas con alguna diferencia.

El propio README del paquete dejaba clara la frontera antes de que hubiera que adivinarla: “this is a component library, not a drop-in blog… routes stay in each app.” Una ruta RSS completa pertenece a un sitio. Pero la forma de un ítem RSS, título, enlace, descripción, categorías, construidos a partir de un post, no le importa a qué sitio pertenece. Así que se dividió: un helper puro de mapeo de datos, buildRssItems, va en el paquete. La ruta real, la llamada real a rss(), se queda local en cada sitio. Es el mismo patrón que el paquete ya usa para su helper de JSON-LD.

La parte que realmente tomó tiempo no fue el código, fue la consecuencia. Este paquete se distribuye como un tarball de GitHub fijado a un tag, no como un paquete del registro de npm. Una vez que el lockfile de un consumidor registra el hash de ese tarball, el tag queda efectivamente congelado. Subirlo de tag sin cuidado y un bug deja de ser un arreglo rápido, pasa a ser un tag nuevo y una segunda migración.

Así que antes de etiquetar nada, se comprobó que el cambio funcionaba. npm pack en el repo del paquete, instalar el tarball resultante localmente en imperfectsystems.com, hacer build, y leer el XML generado de verdad. Solo después de confirmar tres posts, orden correcto, enlaces funcionando, se revirtió esa instalación de prueba y se cortó el tag real.

Después hubo un detalle que casi se pasa por alto: se revirtieron las ediciones de prueba de package.json, lo cual es correcto, pero eso significaba que la próxima subida real tenía que traer el tarball realmente publicado de GitHub, no el archivo local recién probado. Si se hubiera confirmado un lockfile apuntando a una ruta local, el CI del sitio, que no tiene acceso al sistema de archivos de esta máquina, habría fallado en el próximo deploy. Se confirmó que el tag realmente estaba en vivo en GitHub (siguiendo la redirección hasta un 200 real) antes de tocar siquiera la dependencia del sitio.

Ya en producción, el feed volvió con el content-type equivocado en la primera revisión en vivo, text/html, sirviendo la página 404. Al reintentar unos segundos después: application/xml, cuerpo correcto. Una caché de borde desactualizada en un POP de Cloudflare todavía no se había puesto al día. Es un buen recordatorio de que “el deploy terminó” y “cada nodo de borde está de acuerdo con el deploy” no son la misma afirmación, sobre todo justo en el momento en que termina un rollout.

El feed valida limpio contra el validador de W3C ahora. Una recomendación, no un error: le falta un enlace atom autorreferenciado, que es simplemente el comportamiento por defecto de @astrojs/rss. Eso se dejó como está.

Lecturas relacionadas