Saltar al contenido
crawlforgeEnglish
Producto3 de noviembre de 20267 min de lecturaRead in English

Instalar CrawlForge sin Rust

La 0.22.0 se instala con Homebrew, un instalador de una línea o cargo, con binarios que GitHub compila gratis. Por el camino se rompieron cinco cosas.

Hasta la 0.21.0 la única forma de tener CrawlForge era clonar el repositorio y compilarlo con Rust, que pone a prueba la paciencia de cualquiera y es mala manera de probar una herramienta. La 0.22.0 cambia cómo se consigue y deja el motor como estaba: lo que comprueba y lo que escribe es lo mismo que en la 0.21.0. Lo nuevo es que ya la puede instalar alguien que no ha escrito cargo en su vida.

brew install dcarrero/tap/crawlforge                    # macOS y Linux
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/dcarrero/crawlforge/releases/latest/download/crawlforge-installer.sh | sh
powershell -ExecutionPolicy Bypass -c "irm https://github.com/dcarrero/crawlforge/releases/latest/download/crawlforge-installer.ps1 | iex"
cargo install crawlforge                                 # Rust 1.88 o posterior

En la última versión publicada hay binarios para macOS en Apple Silicon e Intel, Linux en x86_64 y ARM64 y Windows en x86_64, cada uno con su suma de verificación. En crates.io hay tres paquetes: crawlforge, que es la línea de comandos, y el motor y el catálogo de reglas por separado, como crawlforge-core y crawlforge-rules.

Un aviso antes de seguir. Los binarios de macOS todavía no están notarizados, y aunque Homebrew los instala sin quejarse, uno descargado a mano necesita xattr -d com.apple.quarantine crawlforge para que Gatekeeper lo deje ejecutarse.

Cómo se compila una versión sin pagar nada

Las versiones las compila GitHub Actions, que es gratis en un repositorio público, con dist 0.34 (antes se llamaba cargo-dist). Basta con subir un tag. A partir de ahí compila para macOS en aarch64 y x86_64, Linux en x86_64 y aarch64 (el de ARM64 en el runner ARM de GitHub) y Windows en x86_64, calcula las sumas de verificación, genera los instaladores para la terminal y para PowerShell, crea la versión en GitHub y sube la fórmula de Homebrew a dcarrero/homebrew-tap. Un tap puede tener varias herramientas, y este ya tenía otro proyecto mío.

En la ejecución de la 0.22.0, Linux tardó entre 2m36s y 2m50s, macOS en Apple Silicon 3m16s, Windows 5m11s y macOS en Intel 10m35s. Casi todo lo de Intel es espera, porque la cola de ese runner es la lenta.

El binario sale de un perfil dist que hereda el perfil release sin tocar nada. Eso importa porque la regresión de rendimiento se mide sobre la compilación release, así que lo que se publica es justo lo que se mide.

El flujo escribe en el tap con un token de GitHub limitado al contenido de ese único repositorio, guardado como secreto del repositorio.

Lo que salió mal, por orden

Windows y los saltos de línea. El CI de la 0.21.0 falló solo en Windows. Un test comparaba byte a byte el JSON Schema publicado con el generado, y al hacer checkout Windows convierte los saltos de línea a CRLF. Ahora el test compara el contenido.

Un test de tiempos en un runner cargado. Hay un test que comprueba que el descubrimiento por sitemap rellena la cola de forma continua y no a tandas. En local pasaba en 0,7 s, pero en el runner de macOS de GitHub, que está compartido y va cargado, tardó 2,1 s dos veces con un umbral de 1,5 s. Subir el umbral a ojo habría hecho pasar el test sin que demostrara nada, así que lo que hice fue volver más lento el sitemap del test, de 600 ms a 1,5 s. Con eso, ir a tandas tardaría como mínimo 4,5 s y rellenar de forma continua unos 1,5 s, y el umbral quedó en 3,5 s, con margen de sobra por los dos lados.

Un tag sin versión. La 0.21.1 se etiquetó y nunca llegó a publicarse. Todas las compilaciones fallaron con profile 'dist' is not defined porque faltaba el perfil en Cargo.toml. El tag ya era público, así que lo dejé como estaba en vez de reescribirlo. La 0.21.2 añadió el perfil y fue la primera versión con binarios, todavía con los nombres antiguos crawlforge-cli-*.

Un cambio de nombre que rompió un enlace. La 0.22.0 renombró el paquete de crawlforge-cli a crawlforge para que se instale con cargo install crawlforge. Eso cambió también el nombre de los ficheros de la versión, y el enlace al instalador que se publicó con la 0.21.2, crawlforge-cli-installer.sh, dejó de funcionar con esta. Por eso la web esperó a la 0.22.0 para explicar cómo instalarla.

Empaquetar para crates.io. Un crate publicado en crates.io solo lleva su propia carpeta. Las diez traducciones vivían en la raíz del repositorio y el código las leía con rutas como ../../locales, de modo que, empaquetado, no habría compilado. Se movieron dentro de crawlforge-rules, que ahora le pasa los textos a la línea de comandos. Antes de publicar desempaqueté los tres crates en una carpeta vacía y los compilé juntos, como si vinieran de crates.io. Salió crawlforge 0.22.0, con la salida en japonés y en polaco bien.

Publicar sin guardar ningún token

La primera publicación en crates.io tenía que ser a mano, con un token de la API limitado a estos tres crates y a publicar. El primer token lo rechazó con un 403 porque tenía mal los permisos, y no se subió nada. El segundo funcionó.

A partir de ahí el flujo de publicación usa Trusted Publishing de crates.io. El flujo demuestra quién es ante crates.io con el OpenID Connect de GitHub y recibe una credencial de vida corta para esa ejecución. No queda ningún token permanente guardado en ninguna parte, y el manual se revocó y se borró.

El trabajo de los crates consulta además la API de crates.io antes de publicar y se salta las versiones que ya están, así que al relanzarlo no intenta publicar la misma versión dos veces. Con la 0.22.0 hizo justo eso, en 9 segundos.

Comprobaciones que ahora corren en GitHub

cargo-deny, con el deny.toml del proyecto, se ejecuta en cada pull request, en cada push y todos los lunes. Lo del lunes es porque un aviso nuevo de RustSec puede aparecer sin que nadie toque el código.

Cada pull request que toca código lleva también un A/B de rendimiento. La base y la rama se compilan en el mismo runner y se miden en seis rondas alternas, y el resumen del trabajo enseña una tabla. Nunca bloquea la pull request. En el primero, la mediana de la base fue de 106.567 elementos por segundo y la de la rama de 106.046, un −0,5 %, con rondas entre 102.527 y 110.510 (más o menos ±3 %). En mi portátil, el mismo banco de pruebas había llegado a moverse un 20 % cuando la máquina estaba ocupada compilando otras cosas, y por eso se fue a un runner.

Un test falla ahora si se separan los números de versión que tienen que coincidir: el del workspace, los de las dos dependencias internas y el del package.json que esta web instala por tag.

Probado en un Mac

Antes de escribir esto instalé la 0.22.0 de las tres maneras en un Mac. Con Homebrew fueron unos segundos, 14,6 MB y sin cuarentena de Gatekeeper. El instalador de la terminal y cargo install crawlforge devolvieron los dos crawlforge 0.22.0.

Lo siguiente es notarizar los binarios de macOS y un paquete de winget para Windows.

Se construye en público

Cada dos semanas: mediciones, fallos y ejemplos de uso. Nada más.

← Volver a la bitácora