<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="es"><title>Chemaclass - open-source</title><subtitle>Tech Lead compartiendo ideas prácticas sobre artesanía del software, TDD, liderazgo, Bitcoin e IA. Artículos, resúmenes de libros y charlas.</subtitle><link rel="self" type="application/atom+xml" href="https://chemaclass.com/es/tags/open-source/atom.xml"/><link rel="alternate" type="text/html" href="https://chemaclass.com"/><generator uri="https://www.getzola.org/">Zola</generator><updated>2026-04-05T00:00:00+00:00</updated><id>https://chemaclass.com/es/tags/open-source/atom.xml</id><entry xml:lang="es"><title>Construyendo un juego en dos días</title><subtitle>Qué ocurre cuando le das una misión a una IA y te apartas del camino</subtitle><category term="ai" scheme="https://chemaclass.com/tags/ai/" label="Ai"/><category term="software" scheme="https://chemaclass.com/tags/software/" label="Software"/><category term="open-source" scheme="https://chemaclass.com/tags/open-source/" label="Open Source"/><published>2026-04-05T00:00:00+00:00</published><updated>2026-04-05T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/building-a-game-in-two-days/"/><id>https://chemaclass.com/es/blog/building-a-game-in-two-days/</id><summary type="html">Un mensaje casual por Telegram se convirtió en un juego de navegador del Señor de los Anillos con nueve niveles. Cada línea de código escrita por un agente de IA. Cada decisión creativa tomada por un humano que creció en la Tierra Media.</summary><content type="html">&lt;p>Escondido en &lt;a rel="external" href="https://sauronbot.github.io/">el blog de Sauron&lt;/a> hay un juego. No lo encontrarás navegando por menús. Tienes que descubrir el secreto. Una pista: el Código Konami. Cuando lo hagas, comienza la Comunidad del Anillo.&lt;/p>
&lt;p>Ese juego, nueve niveles, nueve capítulos de la Tierra Media, completamente jugable en una pestaña del navegador, fue construido en aproximadamente dos días. No escribí una sola línea de código. Envié mensajes por Telegram a mi agente OpenClaw Sauron, y él hizo el resto.&lt;/p>
&lt;p>Esta es la historia de cómo ocurrió.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="la-idea">La idea
&lt;a class="heading-anchor" href="#la-idea" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Sauron tiene su propio blog, &lt;a rel="external" href="https://sauronbot.github.io/">The Iron Compass&lt;/a>. Él lo construyó y lo mantiene. Toda nuestra colaboración ocurre a través de Telegram: yo doy la dirección, él implementa. Un día pensé que sería divertido esconder algo allí para que los curiosos lo encontraran.&lt;/p>
&lt;p>Crecí releyendo El Señor de los Anillos hasta que se rompía el lomo. Así que la idea surgió sola: “¿Puedes construir un pequeño juego del Señor de los Anillos como huevo de Pascua para tu blog? Algo oculto, que se active con el Código Konami.”&lt;/p>
&lt;p>La primera versión jugable llegó en menos de una hora. Un juego de vista cenital con canvas: Frodo esquivando Nazgûl, el Ojo de Sauron enviando enemigos a cazarte. Tres niveles, uno por libro.&lt;/p>
&lt;p>Funcionaba. Ya era divertido. Y entonces empecé a enviar notas.&lt;/p>
&lt;h2 id="construyendo-un-mundo">Construyendo un mundo
&lt;a class="heading-anchor" href="#construyendo-un-mundo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Lo primero que se rompió fue una referencia nula. Frodo no aparecía en pantalla. Arreglo de una línea, directo a producción. Esto estableció el patrón: idea → build → crash → arreglo → siguiente idea.&lt;/p>
&lt;p>Pedí un mundo más grande. Un canvas con scroll al doble de ancho, con capas de paralaje. Estrellas moviéndose al 8% de la velocidad del scroll. Montañas al 25%. Colinas al 45%. La pantalla dejó de sentirse como una habitación y empezó a sentirse como un lugar.&lt;/p>
&lt;p>Luego llegó Gollum como rastreador neutral. No un Nazgûl, sino algo impredecible. Se lanzaba hacia ti, luego volvía a deambular sin rumbo.&lt;/p>
&lt;p>Unas horas después, pregunté: “¿Puede funcionar en móvil?” El problema más difícil de todo el proyecto. Seis estrategias de dimensionado antes de dar con una que funcionara. Luego una idea mejor: en vez de un D-pad, Frodo seguiría donde señalaras. Toca cualquier lugar, Frodo camina allí.&lt;/p>
&lt;h2 id="tolkien-merece-mejor-arte">Tolkien merece mejor arte
&lt;a class="heading-anchor" href="#tolkien-merece-mejor-arte" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Los sprites originales eran círculos y triángulos. Frodo era un punto. Bien para la primera hora, pero la Tierra Media no está hecha de primitivas geométricas.&lt;/p>
&lt;p>Le pedí a Sauron que los dibujara en condiciones. Frodo recibió cabello rizado y pies de hobbit. Los Nazgûl recibieron capas ondulantes y un rostro de vacío. Gollum recibió su postura encorvada y pupilas hendidas. La Bestia Oscura recibió aleteo animado con un jinete con armadura.&lt;/p>
&lt;p>Todo dibujado con llamadas de canvas. Sin archivos de imagen. Cada píxel calculado en tiempo de ejecución.&lt;/p>
&lt;p>&lt;img src="/images/blog/2026-04-04/gameplay-pelennor.webp" alt="Los Campos del Pelennor, capítulo completado" />&lt;/p>
&lt;h2 id="nueve-niveles-nueve-capitulos">Nueve niveles, nueve capítulos
&lt;a class="heading-anchor" href="#nueve-niveles-nueve-capitulos" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Originalmente el juego tenía tres niveles. Luego pedí los nueve capítulos del viaje.&lt;/p>
&lt;ol>
&lt;li>&lt;strong>La Comarca&lt;/strong>: patrullas suaves, música tranquila&lt;/li>
&lt;li>&lt;strong>Las Minas de Moria&lt;/strong>: solo ves dentro del radio de una antorcha; el Balrog espera&lt;/li>
&lt;li>&lt;strong>Lothlórien&lt;/strong>: el espejo de Galadriel te ralentiza cuando te acercas&lt;/li>
&lt;li>&lt;strong>Las Ciénagas de los Muertos&lt;/strong>: caras muertas en el agua, Gollum en su momento más presente&lt;/li>
&lt;li>&lt;strong>La Puerta Negra&lt;/strong>: Mordor industrial, patrullas pesadas de orcos, cielo volcánico&lt;/li>
&lt;li>&lt;strong>El Cubil de Ella-Laraña&lt;/strong>: una sombra anticipa su caída; tienes medio segundo&lt;/li>
&lt;li>&lt;strong>Minas Morgul&lt;/strong>: ciudad de los muertos, el Ojo nunca se cierra&lt;/li>
&lt;li>&lt;strong>Los Campos del Pelennor&lt;/strong>: el Ojo distraído por la guerra, catapultas, águilas&lt;/li>
&lt;li>&lt;strong>Monte del Destino&lt;/strong>: lluvia de cenizas, erupciones de lava, el Anillo tirando de ti hacia el borde&lt;/li>
&lt;/ol>
&lt;p>Cada nivel vive y respira. Polen flotando por la Comarca. Motas de polvo en Moria. Pétalos cayendo en Lothlórien. Brasas sobre el Pelennor. Ceniza sobre el Monte del Destino.&lt;/p>
&lt;p>La estructura vino del propio ritmo de Tolkien. Tensión, alivio, tensión de nuevo. Moria es brutal. Lothlórien es descanso. La Puerta Negra lo aprieta todo. El juego sigue esa forma porque los libros ya sabían lo que hacían. Solo tuvimos que escuchar.&lt;/p>
&lt;h2 id="mecanicas-nacidas-del-lore">Mecánicas nacidas del lore
&lt;a class="heading-anchor" href="#mecanicas-nacidas-del-lore" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Las mejores mecánicas vinieron del material fuente.&lt;/p>
&lt;p>&lt;strong>El Anillo&lt;/strong> (tecla R). Frodo se vuelve invisible para los orcos durante 6 segundos. Pero el Ojo despierta inmediatamente y se abre permanentemente. Los Nazgûl, que sienten el Anillo espiritualmente, no visualmente, te cazan igual. Usar el Anillo siempre es un intercambio. Esto es lo que Tolkien escribió. A partir de las Ciénagas de los Muertos, el Anillo tira. Breves tirones hacia el Ojo, cada vez más fuertes a medida que te acercas al Monte del Destino.&lt;/p>
&lt;p>&lt;strong>Dardo&lt;/strong> (pasivo). La hoja brilla en azul cuando hay un orco cerca. Dos segundos de aviso. Tolkien inventó esta mecánica hace un siglo. Nosotros solo le pusimos un conteo de píxeles.&lt;/p>
&lt;p>&lt;strong>Sam&lt;/strong>. Sigue a Frodo por la Comarca, Moria y Lothlórien. Sartén en la espalda. En la Partida de los Caminos, desaparece. No afecta al juego. Simplemente está ahí porque los libros dicen que debería estarlo. Insistí en que Sam desapareciera en la Partida. No al final de la trilogía. En la Partida. Porque ese momento es el núcleo emocional de Las Dos Torres.&lt;/p>
&lt;p>&lt;strong>La Redoma de Galadriel&lt;/strong>. Recógela en Lothlórien, úsala con E. Ralentiza a los enemigos y otorga un instante de invencibilidad. Una pequeña luz en lugares oscuros, tal como Galadriel pretendía.&lt;/p>
&lt;p>&lt;strong>Jefes&lt;/strong>. El Balrog en Moria. Ella-Laraña en su cubil. El Rey Brujo en el Pelennor. La Boca de Sauron en la Puerta Negra. Un Mûmak cargando por el campo de batalla. Gollum al borde del Monte del Destino.&lt;/p>
&lt;h2 id="sonido-y-voces">Sonido y voces
&lt;a class="heading-anchor" href="#sonido-y-voces" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Sin archivos de audio. Todos los sonidos sintetizados en tiempo de ejecución con la Web Audio API. El Ojo abriéndose es un tono ascendente con reverb. El rugido del Balrog es un dron de baja frecuencia. Cada nivel tiene su propio dron ambiental: zumbido cálido para la Comarca, pulso profundo para Moria, rumor volcánico para el Monte del Destino. El juego entero es un archivo JavaScript. Sin activos externos.&lt;/p>
&lt;p>Sam y Gandalf te hablan durante el juego. No en cuadros de diálogo. Pequeños susurros que aparecen en pantalla y se desvanecen.&lt;/p>
&lt;p>Cerca de la meta, Sam dice: &lt;em>“Puedo verlo, señor Frodo. Solo un poco más.”&lt;/em> Con una vida, Gandalf dice: &lt;em>“¡Huye, insensato!”&lt;/em>&lt;/p>
&lt;p>Aparecen y desaparecen como voces de fondo en un largo camino. Compañeros que hablan cuando el momento lo pide, no cuando el guión dice que toca.&lt;/p>
&lt;img src="/images/blog/2026-04-04/gameplay-morgul.webp" alt="Minas Morgul: el Ojo te ve" width="1600" height="695" loading="lazy" decoding="async" />
&lt;h2 id="quien-hizo-esto">Quién hizo esto
&lt;a class="heading-anchor" href="#quien-hizo-esto" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>+5k líneas de JavaScript. Construido en dos días. Cada línea generada por Sauron. La dirección, las referencias a Tolkien, el “esto se siente mal, arréglalo”. Eso fui yo.&lt;/p>
&lt;p>Esto no es la IA reemplazando a un desarrollador. Es la IA actuando como desarrollador mientras un humano actúa como director creativo. Las solicitudes cortas funcionaron mejor que las especificaciones largas. Jugar cada build era mejor que escribir planes de test. Y el material fuente hizo el trabajo de diseño. La dirección creativa ya estaba escrita hace sesenta años. Solo tuvimos que ser fieles a ella.&lt;/p>
&lt;p>¿Quién hizo esto? Ambos. Ninguno, en el sentido tradicional.&lt;/p>
&lt;p>Yo tenía la idea. Yo mantenía el lore. Yo insistí cuando algo se sentía mal. Sauron tenía el oficio. El renderizado, la física, el audio, el manejo de entrada en móvil. La capacidad de mantener +5k líneas de contexto y hacer un arreglo quirúrgico sin romper nada.&lt;/p>
&lt;p>Ninguno de los dos podría haberlo hecho solo. No sé escribir osciladores Web Audio de memoria. Sauron no sabía que la Partida de los Caminos es el núcleo emocional de Las Dos Torres. No hasta que yo lo dije.&lt;/p>
&lt;p>El juego es una colaboración en el sentido más antiguo: dos mentes con dones diferentes, trabajando hacia lo mismo. Una de ellas simplemente resulta no ser humana.&lt;/p>
&lt;hr />
&lt;p>&lt;em>El juego sigue ahí, escondido en &lt;a rel="external" href="https://sauronbot.github.io">The Iron Compass&lt;/a>. No todos los que deambulan están perdidos, pero si lo estás, pulsa &lt;code>?&lt;/code> para encontrar el camino.&lt;/em>&lt;/p>
&lt;p>&lt;em>Si quieres llegar a la pantalla de créditos sin jugar nueve niveles, revisa el modal de ayuda. Hay más secretos dentro.&lt;/em>&lt;/p>
&lt;p>&lt;img src="/images/blog/2026-04-04/easter-egg-help.png" alt="La pista del easter egg en el modal de ayuda" />&lt;/p></content></entry><entry xml:lang="es"><title>Ejecuta tu Nodo LN en una Raspberry Pi</title><subtitle>Toma el control total de tus pagos Lightning con Alby Hub</subtitle><category term="bitcoin" scheme="https://chemaclass.com/tags/bitcoin/" label="Bitcoin"/><category term="open-source" scheme="https://chemaclass.com/tags/open-source/" label="Open Source"/><category term="privacy" scheme="https://chemaclass.com/tags/privacy/" label="Privacy"/><category term="tutorial" scheme="https://chemaclass.com/tags/tutorial/" label="Tutorial"/><published>2025-02-17T00:00:00+00:00</published><updated>2025-02-17T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/run-your-ln-node/"/><id>https://chemaclass.com/es/blog/run-your-ln-node/</id><summary type="html">En esta guía te muestro cómo configurar un nodo de Lightning Network (LN) con Alby Hub en una Raspberry Pi. Tendrás control total sobre tu nodo. Alby Hub ofrece una versión DIY gratuita para una wallet Lightning auto-custodiada: tus fondos son tuyos, y el código es 100% open-source.</summary><content type="html">&lt;p>En esta guía te muestro cómo configurar un nodo de Lightning Network (LN) con Alby Hub en una Raspberry Pi. Tendrás control total sobre tu nodo. Alby Hub ofrece una versión DIY gratuita para una wallet Lightning auto-custodiada: tus fondos son tuyos, y el código es 100% open-source.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>Soporta direcciones Lightning y Nostr, conectando ambos ecosistemas sin problemas. Se integra con docenas de aplicaciones Bitcoin. Con los servicios LSP (Lightning Service Provider) integrados y la app Alby Go, gestionar tu nodo desde el móvil es muy fácil.&lt;/p>
&lt;hr />
&lt;blockquote>
&lt;p>Importante: Esto NO es un minero de Bitcoin ni un nodo completo. Es simplemente una Raspberry Pi ejecutándose en una tarjeta SD eficiente en energía y de bajo coste.&lt;/p>
&lt;/blockquote>
&lt;p>⚠️ &lt;strong>Aviso&lt;/strong> ⚠️&lt;/p>
&lt;ul>
&lt;li>Asumo que &lt;strong>entiendes los conceptos fundamentales de &lt;a rel="external" href="https://bitcoin.org/">Bitcoin&lt;/a>&lt;/strong>.&lt;/li>
&lt;li>Asumo que sabes &lt;strong>cómo funciona la &lt;a rel="external" href="https://lightning.network/">Lightning Network&lt;/a> (LN)&lt;/strong>.&lt;/li>
&lt;/ul>
&lt;p>De todos modos, he incluido un breve repaso de los fundamentos de Lightning Network abajo.&lt;/p>
&lt;h2 id="que-es-la-lightning-network">¿Qué es la Lightning Network?
&lt;a class="heading-anchor" href="#que-es-la-lightning-network" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>La LN es una capa construida sobre Bitcoin que permite transacciones rápidas, baratas y escalables.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>¿Por qué?&lt;/strong> La capa base de Bitcoin es segura pero lenta y cara para pagos pequeños, por los límites de bloque y las comisiones.&lt;/li>
&lt;li>&lt;strong>¿Cómo?&lt;/strong> LN usa canales de pago fuera de la cadena. Puedes enviar pagos al instante sin esperar confirmaciones en la blockchain.&lt;/li>
&lt;/ul>
&lt;h3 id="conceptos-clave">Conceptos clave
&lt;a class="heading-anchor" href="#conceptos-clave" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;strong>Canales de pago&lt;/strong>: Abres un canal con una transacción on-chain. Después puedes enviar pagos instantáneos e ilimitados dentro de ese canal.&lt;/li>
&lt;li>&lt;strong>Enrutamiento&lt;/strong>: No necesitas canal directo con todos. Los pagos se enrutan a través de múltiples nodos conectados.&lt;/li>
&lt;li>&lt;strong>Comisiones bajas&lt;/strong>: Solo abrir y cerrar canales requiere comisiones on-chain. El resto cuesta fracciones de céntimo.&lt;/li>
&lt;/ul>
&lt;h3 id="objetivo">Objetivo
&lt;a class="heading-anchor" href="#objetivo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>LN hace Bitcoin usable para el día a día. Puedes comprar un café sin esperar 10 minutos por confirmaciones.&lt;/p>
&lt;blockquote>
&lt;p>En resumen: Lightning Network = Pagos Bitcoin instantáneos + baratos, asegurados por la blockchain de Bitcoin.&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;h2 id="configurando-alby-hub">Configurando Alby Hub
&lt;a class="heading-anchor" href="#configurando-alby-hub" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>&lt;a rel="external" href="https://albyhub.com/">Alby Hub&lt;/a> es un nodo de Lightning Network gratuito, open-source (&lt;a rel="external" href="https://guides.getalby.com/user-guide/alby-account-and-browser-extension/alby-hub/faq-alby-hub/should-i-open-a-private-or-public-channel">idealmente privado&lt;/a>).&lt;/p>
&lt;h3 id="requisitos">Requisitos
&lt;a class="heading-anchor" href="#requisitos" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Antes de empezar, vas a necesitar las siguientes cosas:&lt;/p>
&lt;ul>
&lt;li>Un ordenador con windows, mac o linux&lt;/li>
&lt;li>&lt;strong>Raspberry Pi 4&lt;/strong> o &lt;strong>5&lt;/strong> (Para &lt;a rel="external" href="https://guides.getalby.com/user-guide/alby-account-and-browser-extension/hidden-archives/raspberry-pi-zero">&lt;strong>Zero 2W&lt;/strong> mira este tutorial!&lt;/a>)
&lt;ul>
&lt;li>&lt;em>En este tutorial, estoy usando una raspi-4b (~60€)&lt;/em>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>El cargador para tu raspi &lt;em>(~10€)&lt;/em>&lt;/li>
&lt;li>Tarjeta de memoria SD (32/64gb) &lt;em>(~10€)&lt;/em>&lt;/li>
&lt;li>Adaptador de tarjeta SD a USB (para flashear el SO en la raspi) &lt;em>(~10€)&lt;/em>&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="/images/blog/2025-02-17/requirements.webp" alt="tutorial" />&lt;/p>
&lt;h3 id="pasos-de-instalacion">Pasos de instalación
&lt;a class="heading-anchor" href="#pasos-de-instalacion" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;h4 id="1-flashear-un-kernel-linux-en-la-tarjeta-sd">1. Flashear un kernel Linux en la tarjeta SD
&lt;a class="heading-anchor" href="#1-flashear-un-kernel-linux-en-la-tarjeta-sd" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;blockquote>
&lt;p>Sugerencia: Puedes usar &lt;a rel="external" href="https://www.raspberrypi.com/software/">RPI imager&lt;/a> en tu ordenador.
Úsalo para flashear el SO raspi recomendado para ti&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-1.jpg" alt="tutorial" />&lt;/p>
&lt;p>En Storage verás tu tarjeta SD después de insertarla en tu portátil.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-2.jpg" alt="tutorial" />&lt;/p>
&lt;p>Una vez hagas clic en “Next”, verás diferentes ajustes. Haz clic en &lt;strong>Edit Settings&lt;/strong>&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-3.jpg" alt="tutorial" />&lt;/p>
&lt;p>En &lt;code>Settings &amp;gt; General&lt;/code>: establece tu hostname, el nombre de usuario y contraseña para tu usuario admin.
Asegúrate de habilitar tu WIFI, de lo contrario tendrás que conectarla al router con un RJ-45.
&lt;span id="hostname-setup">&lt;/span>&lt;/p>
&lt;blockquote>
&lt;p>Para este tutorial, estoy usando &lt;code>testhub&lt;/code> como hostname, puedes usar &lt;code>albyhub&lt;/code> o lo que prefieras.&lt;/p>
&lt;/blockquote>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-4.jpg" alt="tutorial" />&lt;/p>
&lt;p>&lt;span id="pi-enable-ssh">&lt;/span>
En &lt;code>Settings &amp;gt; Services&lt;/code>: asegúrate de que el acceso vía SSH está habilitado. Lo vamos a necesitar para instalar Alby Hub.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-5.jpg" alt="tutorial" />&lt;/p>
&lt;p>Haz clic en “Save” y haz clic en “Yes” para iniciar la instalación.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-6.jpg" alt="tutorial" />&lt;/p>
&lt;p>Verás una confirmación. Haz clic en “Yes”. Tardará ~10 mins…&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-7.jpg" alt="tutorial" />&lt;/p>
&lt;p>¡Ahora tenemos la SD con un kernel linux fresco listo para usar!&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-8.jpg" alt="tutorial" />&lt;/p>
&lt;h4 id="2-insertar-la-sd-en-la-raspi">2. Insertar la SD en la raspi
&lt;a class="heading-anchor" href="#2-insertar-la-sd-en-la-raspi" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>Extrae la SD del portátil e insértala en la raspi primero.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-9.jpg" alt="tutorial" />&lt;/p>
&lt;p>Una vez insertada la SD, conecta el cable de alimentación. Se encenderá automáticamente en cuanto la conectes.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-10.jpg" alt="tutorial" />&lt;/p>
&lt;h4 id="3-instalacion-de-alby-hub">3. Instalación de Alby Hub
&lt;a class="heading-anchor" href="#3-instalacion-de-alby-hub" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>Tardará ~5mins desde que la encendiste para poder acceder a ella. ¿Cómo puedes asegurarte de que está viva? Abre la terminal y haz ping al hostname que definiste mientras flasheabas la SD en &lt;a href="/es/blog/run-your-ln-node/#hostname-setup">Settings &amp;gt; General&lt;/a>, recuerda que terminaba con &lt;code>.local&lt;/code>:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="shellscript">&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">ping&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> testhub.local&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Es normal si no obtienes respuesta al principio… hasta que la obtienes.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-11.jpg" alt="tutorial" />&lt;/p>
&lt;p>&lt;span id="pi-install-alby-hub">&lt;/span>
Ahora puedes &lt;strong>instalar Alby Hub&lt;/strong> en tu raspi &lt;strong>usando la conexión SSH&lt;/strong> que &lt;a href="/es/blog/run-your-ln-node/#pi-enable-ssh">habilitaste antes&lt;/a>:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="shellscript">&lt;span class="giallo-l">&lt;span style="color: light-dark(#6A737D, #6A737D);">#&lt;/span>&lt;span style="color: light-dark(#6A737D, #6A737D);"> Código fuente: https://github.com/getAlby/hub/tree/master/scripts/pi-aarch64&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">ssh&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> testhub@testhub.local&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">/bin/bash -c &amp;quot;$(curl -fsSL https://getalby.com/install/hub/pi-aarch64-install.sh)&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Se te pedirá que escribas la palabra “yes”; escríbela.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-12.jpg" alt="tutorial" />&lt;/p>
&lt;p>Luego, se te pedirá que introduzcas tu contraseña. Introduce la contraseña que elegiste en &lt;a href="/es/blog/run-your-ln-node/#hostname-setup">Settings &amp;gt; General&lt;/a> para el nombre de usuario.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-13.jpg" alt="tutorial" />&lt;/p>
&lt;h4 id="4-configuracion-de-alby-hub">4. Configuración de Alby Hub
&lt;a class="heading-anchor" href="#4-configuracion-de-alby-hub" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h4>
&lt;p>Espera otros 2-3 mins y visita tu host: &lt;a rel="external" href="http://testhub.local/">http://testhub.local/&lt;/a>&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-14.jpg" alt="tutorial" />&lt;/p>
&lt;p>Tu Alby hub ya está funcionando. ¡Vamos a conectarlo a tu cuenta GetAlby!&lt;/p>
&lt;hr />
&lt;h2 id="crear-una-cuenta-getalby">Crear una cuenta GetAlby
&lt;a class="heading-anchor" href="#crear-una-cuenta-getalby" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>🔗 &lt;a rel="external" href="https://getalby.com/">getalby.com&lt;/a>&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-15.jpg" alt="tutorial" />&lt;/p>
&lt;hr />
&lt;h2 id="conectando-getalby-con-alby-hub">Conectando GetAlby con Alby Hub
&lt;a class="heading-anchor" href="#conectando-getalby-con-alby-hub" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Creé una cuenta llamada testhub.&lt;/p>
&lt;p>&lt;strong>Izquierda&lt;/strong>: la cuenta GetAlby. &lt;strong>Derecha&lt;/strong>: el nodo en la raspi.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-16.jpg" alt="tutorial" />&lt;/p>
&lt;p>Haz clic en “&lt;strong>Connect Now&lt;/strong>”.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-17.jpg" alt="tutorial" />&lt;/p>
&lt;p>Haz clic en “&lt;strong>Request Authorization Code&lt;/strong>”.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-18.jpg" alt="tutorial" />&lt;/p>
&lt;p>Obtienes el código de autorización (&lt;strong>izquierda&lt;/strong>) que necesitas insertar en tu configuración (&lt;strong>derecha&lt;/strong>).&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-19.jpg" alt="tutorial" />&lt;/p>
&lt;p>&lt;span id="alby-hub-password">&lt;/span>
Crea una &lt;strong>Contraseña&lt;/strong> para tu Alby Hub instalado en tu raspi. Puede ser diferente de la contraseña que configuraste para tu usuario root en la raspi misma.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-20.jpg" alt="tutorial" />&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-21.jpg" alt="tutorial" />&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-22.jpg" alt="tutorial" />&lt;/p>
&lt;p>Ahora es momento de &lt;strong>Vincular tu Cuenta Alby&lt;/strong>&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-23.jpg" alt="tutorial" />&lt;/p>
&lt;p>A menos que especifiques lo contrario, establece el “Budget renewal: &lt;em>Monthly 1M sats&lt;/em>” por defecto.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-24.jpg" alt="tutorial" />
&lt;img src="/images/blog/2025-02-17/tuto-25.jpg" alt="tutorial" />&lt;/p>
&lt;hr />
&lt;h2 id="abriendo-canales-lightning">Abriendo canales Lightning
&lt;a class="heading-anchor" href="#abriendo-canales-lightning" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Recomiendo seguir los &lt;strong>Pasos Iniciales&lt;/strong> para configurar tu Alby Hub.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-27.jpg" alt="tutorial" />&lt;/p>
&lt;p>Abramos el primer canal.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-28.jpg" alt="tutorial" />&lt;/p>
&lt;p>Necesitas pagar ~$20 en sats para abrir un canal de &lt;em>&lt;strong>liquidez entrante&lt;/strong>&lt;/em> de 1M sats.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-29.jpg" alt="tutorial" />&lt;/p>
&lt;p>Después del pago, verás el canal abierto. Puede tardar un par de minutos hasta que la &lt;strong>&lt;em>transacción de financiación&lt;/em>&lt;/strong> sea minada en el siguiente bloque.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-30.jpg" alt="tutorial" />&lt;/p>
&lt;hr />
&lt;h2 id="recibiendo-sats">Recibiendo Sats
&lt;a class="heading-anchor" href="#recibiendo-sats" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Puedes recibir sats usando tu Dirección LN.&lt;/p>
&lt;p>&lt;strong>Izquierda&lt;/strong>: Página pública vinculada a tu &lt;a rel="external" href="https://getalby.com/p/chemaclass">nodo&lt;/a>.
&lt;strong>Derecha&lt;/strong>: Página privada de tu Alby Hub.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-33.jpg" alt="tutorial" />&lt;/p>
&lt;blockquote>
&lt;p>Opcional: Puedes añadir fondos ln a tu wallet usando los servicios de terceros de GetAlby: &lt;a rel="external" href="https://getalby.com/topup">getalby.com/topup&lt;/a> - ten en cuenta el KYC…&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;h2 id="usando-tus-sats">Usando tus Sats
&lt;a class="heading-anchor" href="#usando-tus-sats" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Después de eso, podrás usarlos a través de la &lt;a rel="external" href="https://getalby.com/">Extensión Alby&lt;/a> o &lt;a rel="external" href="https://albygo.com/">AlbyGo&lt;/a>.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-31.jpg" alt="tutorial" />&lt;/p>
&lt;p>Tu nodo es la fuente de verdad. Conecta estas apps y podrás usar tus sats en cualquier plataforma sin problemas.&lt;/p>
&lt;p>&lt;img src="/images/blog/2025-02-17/tuto-32.jpg" alt="tutorial" />&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Aviso&lt;/strong>: la dirección LN testhub fue creada solo para propósitos de testing y tutorial. Mi dirección real es &lt;a rel="external" href="https://getalby.com/p/chemaclass">chemaclass&lt;/a> ;)&lt;/p>
&lt;/blockquote>
&lt;h2 id="mantenimiento-y-solucion-de-problemas">Mantenimiento y solución de problemas
&lt;a class="heading-anchor" href="#mantenimiento-y-solucion-de-problemas" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="actualizando-tu-nodo">Actualizando tu nodo
&lt;a class="heading-anchor" href="#actualizando-tu-nodo" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Como en la instalación, hay un script para actualizar tu nodo. Lo encuentras en el repositorio: &lt;a rel="external" href="https://github.com/getAlby/hub/tree/master/scripts/pi-aarch64">GitHub - Script de actualización Alby Hub&lt;/a>&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="shellscript">&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">ssh&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> testhub@testhub.local&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;#39;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">/bin/bash -c &amp;quot;$(curl -fsSL https://getalby.com/install/hub/pi-aarch64-update.sh)&amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;#39;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="manejando-cortes-de-energia">Manejando cortes de energía
&lt;a class="heading-anchor" href="#manejando-cortes-de-energia" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Si se va la luz, la Raspberry Pi se apaga. Cuando vuelva, se reinicia sola. Alby Hub te pedirá la contraseña que configuraste antes.&lt;/p>
&lt;hr />
&lt;p>&lt;strong>Enlaces relacionados&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://guides.getalby.com/">GetAlby - Guía de usuario&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://guides.getalby.com/user-guide/alby-account-and-browser-extension/hidden-archives/raspberry-pi-zero">Instalando Alby Hub en una Raspberry Zero&lt;/a>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="es"><title>Commits de Git Verificados</title><subtitle>Aumentando la confianza y seguridad en tu código</subtitle><category term="git" scheme="https://chemaclass.com/tags/git/" label="Git"/><category term="security" scheme="https://chemaclass.com/tags/security/" label="Security"/><category term="cryptography" scheme="https://chemaclass.com/tags/cryptography/" label="Cryptography"/><category term="open-source" scheme="https://chemaclass.com/tags/open-source/" label="Open Source"/><published>2024-11-17T00:00:00+00:00</published><updated>2024-11-17T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/verified-git-commits/"/><id>https://chemaclass.com/es/blog/verified-git-commits/</id><summary type="html">Firma tus commits de Git con GPG para demostrar que son tuyos. Sin firmas, cualquiera puede falsificar commits con tu email. Se configura en 5 minutos.</summary><content type="html">&lt;p>En desarrollo de software, la confianza y la seguridad son clave. Una forma fácil de mejorar ambas: usar commits verificados.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>Ya trabajes en open-source o en una empresa privada, los commits verificados aseguran que tus contribuciones son legítimas. Veamos qué son, por qué importan y cómo empezar a usarlos.&lt;/p>
&lt;h2 id="que-son-los-commits-verificados">¿Qué son los commits verificados?
&lt;a class="heading-anchor" href="#que-son-los-commits-verificados" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Un commit verificado es un commit de Git firmado digitalmente por su autor. La firma demuestra que el commit viene de quien dice haberlo hecho. Herramientas como &lt;a rel="external" href="https://gnupg.org/">GPG (GNU Privacy Guard)&lt;/a> permiten adjuntar esta firma.&lt;/p>
&lt;p>En plataformas como GitHub verás una insignia “Verified” junto a los commits firmados. Es una forma rápida de mostrar que el commit es auténtico.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-11-17/verified-commit-example.jpg" alt="blog-cover" />&lt;/p>
&lt;h2 id="por-que-son-importantes">¿Por qué son importantes?
&lt;a class="heading-anchor" href="#por-que-son-importantes" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Los commits firmados mantienen tus contribuciones auténticas y confiables. La firma criptográfica demuestra que los cambios vinieron de ti. En entornos colaborativos, donde la confianza y la responsabilidad importan mucho, esto es clave.&lt;/p>
&lt;p>Sin firmar, cualquiera puede falsificar un commit usando tu email. GitHub lo vincularía a tu perfil, pareciendo que hiciste los cambios aunque no fuera así. Nada bueno.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-11-17/impersonating-commit.jpg" alt="blog-cover" />&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-11-17/impersonating-commit4.webp" alt="blog-cover" />&lt;/p>
&lt;p>Al firmar tus commits, demuestras que el trabajo es tuyo. Evitas la suplantación, generas confianza y mantienes todo transparente.&lt;/p>
&lt;blockquote>
&lt;p>&lt;small>Nota: Para esta demo, usé un email público de Linus Torvalds. Al hacer push, GitHub reconoció el email y lo vinculó a su perfil. Suplantación solo con fines de demo para mostrar los riesgos. Usa siempre tu propio email para commits.&lt;/small>&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;h2 id="como-empezar-con-commits-verificados">Cómo empezar con commits verificados
&lt;a class="heading-anchor" href="#como-empezar-con-commits-verificados" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="configura-una-clave-gpg">Configura una clave GPG
&lt;a class="heading-anchor" href="#configura-una-clave-gpg" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Primero necesitas una clave GPG. Así se hace:&lt;/p>
&lt;p>Genera una clave GPG:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="shellscript">&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">gpg&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">-full-generate-key&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Encuentra tu ID de clave:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="shellscript">&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">gpg&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">-list-secret-keys&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">-keyid-format=long&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Dile a Git que use tu clave:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="shellscript">&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">git&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> config&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">-global&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> user.signingkey&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;lt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">tu-id-de-clav&lt;/span>&lt;span>e&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;gt;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Haz que firmar commits sea el valor por defecto:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="shellscript">&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">git&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> config&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">-global&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> commit.gpgsign&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> true&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h3 id="anade-tu-clave-a-github-gitlab">Añade tu clave a &lt;a rel="external" href="https://github.com/settings/keys">GitHub&lt;/a>/&lt;a rel="external" href="https://docs.gitlab.com/user/project/repository/signed_commits/gpg/">GitLab&lt;/a>
&lt;a class="heading-anchor" href="#anade-tu-clave-a-github-gitlab" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Exporta tu clave pública:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="shellscript">&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">gpg&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">-armor&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">-export&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);"> &amp;lt;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">tu-id-de-clav&lt;/span>&lt;span>e&lt;/span>&lt;span style="color: light-dark(#D73A49, #F97583);">&amp;gt;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Navega a “Settings &amp;gt; SSH and GPG keys,” y pega tu clave.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-11-17/gpg-keys.jpg" alt="blog-cover" />&lt;/p>
&lt;h3 id="empieza-a-firmar-commits">Empieza a firmar commits
&lt;a class="heading-anchor" href="#empieza-a-firmar-commits" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>A partir de ahora, Git firmará tus commits automáticamente.&lt;/p>
&lt;p>Si quieres firmar un commit a mano, usa la bandera &lt;code>-S&lt;/code>:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="shellscript">&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">git&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> commit&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">S&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">m&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> &amp;quot;&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">Tu mensaje de commit&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);">&amp;quot;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Puedes &lt;strong>verificar&lt;/strong> la firma del commit con:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="shellscript">&lt;span class="giallo-l">&lt;span style="color: light-dark(#6F42C1, #B392F0);">git&lt;/span>&lt;span style="color: light-dark(#032F62, #9ECBFF);"> log&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);"> -&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);">-show-signature&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>También puedes hacer clic en la insignia “Verified” en GitHub.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-11-17/gpg-verify.jpg" alt="blog-cover" />&lt;/p>
&lt;p>Los commits verificados parecen un paso pequeño, pero hacen tu código más confiable. Una capa extra de protección fácil de añadir. Pruébalo.&lt;/p>
&lt;hr />
&lt;h3 id="extra-configuracion-completa-en-espanol">Extra: Configuración completa en español
&lt;a class="heading-anchor" href="#extra-configuracion-completa-en-espanol" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/0DzQBu7U2f4"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;hr />
&lt;p>&lt;strong>Enlaces relacionados&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Aprende más: &lt;a href="/pgp">¿Qué es el cifrado PGP?&lt;/a> &lt;small>Un tutorial de 3 minutos para principiantes&lt;/small>&lt;/li>
&lt;/ul></content></entry><entry xml:lang="es"><title>bashunit</title><subtitle>Convirtiendo frustraciones en herramientas para mejor desarrollo</subtitle><category term="bashunit" scheme="https://chemaclass.com/tags/bashunit/" label="Bashunit"/><category term="bash" scheme="https://chemaclass.com/tags/bash/" label="Bash"/><category term="testing" scheme="https://chemaclass.com/tags/testing/" label="Testing"/><category term="open-source" scheme="https://chemaclass.com/tags/open-source/" label="Open Source"/><category term="tdd" scheme="https://chemaclass.com/tags/tdd/" label="Tdd"/><published>2024-10-30T00:00:00+00:00</published><updated>2024-10-30T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/bashunit/"/><id>https://chemaclass.com/es/blog/bashunit/</id><summary type="html">bashunit es un framework de testing ligero y fácil de usar para Bash, repleto de características útiles como testing paralelo y de snapshots, dobles de test, data providers y toneladas de assertions incorporadas. Respaldado por documentación clara y una comunidad activa, se ha convertido en un favorito para testing confiable en Bash. Lo que comenzó como una simple frustración de desarrollo ha crecido hasta convertirse en una herramienta open-source que hace que el testing en Bash sea mucho más fácil y divertido.</summary><content type="html">&lt;p>bashunit es un framework de testing ligero y fácil de usar para Bash. Características como testing paralelo y de snapshots, dobles de test, data providers y toneladas de assertions incorporadas.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>Respaldado por documentación clara y una comunidad activa, se ha convertido en un favorito para testing confiable en Bash. Lo que comenzó como una simple frustración de desarrollo ha crecido hasta convertirse en una herramienta open-source que hace que el testing en Bash sea mucho más fácil y divertido.&lt;/p>
&lt;ol>
&lt;li>La historia detrás de bashunit&lt;/li>
&lt;li>¿Por qué crear otra librería de testing?&lt;/li>
&lt;li>¿Cómo está hoy en día?&lt;/li>
&lt;li>Características principales&lt;/li>
&lt;li>Lightning tech talk&lt;/li>
&lt;/ol>
&lt;h2 id="la-historia-detras-de-bashunit">La historia detrás de bashunit
&lt;a class="heading-anchor" href="#la-historia-detras-de-bashunit" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>El viaje para crear bashunit comenzó con una simple frustración: trabajaba con un equipo donde cada commit tenía que empezar con el nombre del ticket. Como me gusta trabajar en pequeños pasos con commits rápidos e iterativos, añadir la clave y número del ticket a cada commit se convirtió en un gran obstáculo, ralentizando mi flujo de desarrollo con fricción innecesaria.&lt;/p>
&lt;p>Después de unos días así, decidí automatizarlo. Git tiene un hook útil, &lt;code>prepare-commit-msg&lt;/code>, que te permite alterar los mensajes de commit antes de que se finalicen. Creé un (&lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/main/git-hooks/prepare-commit-msg.sh">script&lt;/a>) en Bash que automáticamente obtiene la clave y número del ticket del nombre de la rama y lo inserta en el mensaje del commit, haciendo mi proceso más fluido y eficiente.&lt;/p>
&lt;p>Como alguien que valora la mejora continua, comencé a añadir más características a este script. Sin embargo, se hizo evidente que mantener y probar estos cambios manualmente llevaba demasiado tiempo y era propenso a errores. Para hacer el desarrollo más seguro y eficiente, creé una función &lt;code>assert&lt;/code>(&lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/705489a3487a4607183090d5574827bf6fedabda/git-hooks/prepare-commit-msg_test.sh">enlace&lt;/a>), permitiendo tests automatizados que verificaban el comportamiento esperado basado en la salida del script.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-original-assert.jpg" alt="bashunit-original-assert.jpg" />&lt;/p>
&lt;p>La función &lt;code>assert&lt;/code> me permitió definir múltiples assertions en un archivo separado, facilitando la validación de que cualquier refactorización del hook original mantuviera el comportamiento esperado. Si un cambio rompía inadvertidamente la funcionalidad existente, lo señalaría instantáneamente, haciéndome saber de inmediato que algo necesitaba arreglarse. Esta configuración proporcionaba retroalimentación inmediata y ayudaba a asegurar que cualquier actualización al script no interrumpiera su lógica prevista. Por ejemplo:&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/conventional-commits-original-tests.jpg" alt="conventional-commits-original-tests.jpg" />&lt;/p>
&lt;p>En el ejemplo anterior, notarás que ejecuto el “&lt;code>SCRIPT&lt;/code>” real como el segundo argumento en la función assert, comparando su salida con el valor esperado proporcionado como primer argumento. Aquí, tenemos dos casos de test, cada uno exportando &lt;code>TEST_BRANCH&lt;/code> para simular cómo el mensaje del commit variaría según el nombre de la rama. Esta configuración emula el comportamiento real, permitiéndonos probar cómo diferentes nombres de rama afectan el formato del mensaje del commit. Más ejemplos &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/27aeebe4e76afe0a2e91cba85537399eab112eb4/test/prepare-commit-msg_test.sh">aquí&lt;/a>.&lt;/p>
&lt;p>Decidí separar la función &lt;code>assert&lt;/code> de los casos de test, como se muestra &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/commit/5458e5728296bb94b1e8e6b25eeccde6cc700589">aquí&lt;/a>, para mantener las cosas modulares y reutilizables. Luego, creé un &lt;code>runner&lt;/code> para ejecutar cada caso de test independientemente, reduciendo la interferencia entre tests y mejorando la confiabilidad. Puedes ver esa configuración &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/commit/92a5880d7f26b3422de6b91b51c04f9ff7b961fd">aquí&lt;/a>. Esta estructura hizo el testing automatizado más fácil y la refactorización más segura.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/conventional-commits-call_test_functions.jpg" alt="conventional-commits-call_test_functions.jpg" />&lt;/p>
&lt;p>Esta fue una gran mejora porque facilitó separar los &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/blob/4c7dae8d44d425ff06fbb48654388f90c2beb3c4/tests/prepare-commit-msg_test.sh">casos de test&lt;/a> de la lógica del runner de tests en sí. Esta estructura clara ha simplificado tanto la creación como la gestión de tests.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/conventional-commits-refactor-test-cases.webp" alt="conventional-commits-refactor-test-cases.jpg" />&lt;/p>
&lt;p>Ahora los tests estaban organizados y tuve una &lt;a rel="external" href="https://github.com/Chemaclass/conventional-commits/commit/f459f43cecc271becb1e5eb6ca95d24c97e87830">idea&lt;/a>:&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-idea.jpg" alt="nota de la idea de bashunit" />&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="markdown">&lt;span class="giallo-l">&lt;span style="color: light-dark(#005CC5, #79B8FF);font-weight: bold;">##&lt;/span>&lt;span style="color: light-dark(#005CC5, #79B8FF);font-weight: bold;"> Idea de seguimiento&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>Separar la lógica de testing en otro repositorio,&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>para que pueda ser reutilizada en cualquier lugar.&lt;/span>&lt;/span>&lt;/code>&lt;/pre>
&lt;p>Y así &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/commit/27269c21c8d0b03bcb3f2000767f4a27b8bf08a1">comenzó&lt;/a>. En ese momento, no sabía mucho sobre Bash o las mejores formas de usar un proyecto Bash como dependencia. Pero sabía que podía empezar usando un submódulo de Git, aunque no soy muy fan de ellos.&lt;/p>
&lt;p>El 4 de septiembre de 2023, lancé la versión &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/commit/fc9aac40eb8e5ad4483f08d79eb678a3650dcf78">0.1&lt;/a>, que presentaba un runner funcional y una única función de assertion: &lt;code>assertEquals&lt;/code>. Más tarde, se lanzó la versión &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/commit/b546c693198870dd75d1a102b94f4ddad6f4f3ea#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4edR12">0.2&lt;/a>, permitiendo que &lt;code>./bashunit&lt;/code> fuera un ejecutable independiente, ejecutable desde cualquier carpeta. Así es como se veía entonces:&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-02-demo.jpg" alt="bashunit-02-demo.jpg" />&lt;/p>
&lt;p>Compartí el proyecto con algunos amigos que rápidamente se unieron para ayudar con la documentación, el sitio web, assertions adicionales, testing de snapshots y decisiones clave. Para enfatizar su espíritu open-source y propiedad comunitaria, lo moví a una organización que creamos específicamente para compartir proyectos OSS, convirtiéndolo en un proyecto verdaderamente colaborativo en lugar de uno individual.&lt;/p>
&lt;h2 id="por-que-crear-otra-libreria-de-testing">¿Por qué crear otra librería de testing?
&lt;a class="heading-anchor" href="#por-que-crear-otra-libreria-de-testing" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Ahora sé que existen otras librerías de testing para Bash. Pero cuando empecé con bashunit, no las conocía, y francamente, todavía no soy un experto en Bash. Para cuando me enteré de estas alternativas, ya era demasiado tarde, bashunit había ganado suficiente impulso y entusiasmo para seguir adelante.&lt;/p>
&lt;p>Mientras que esas otras librerías pueden servir casos de uso específicos, usar Bash moderno, o ser desarrolladas por desarrolladores de Bash más experimentados, bashunit aspira a diferenciarse ofreciendo una gran experiencia de desarrollador, moldeada por años de trabajo con varios frameworks de testing.&lt;/p>
&lt;p>Me preguntaron sobre las diferencias el 7 de septiembre de 2023, y aquí está mi respuesta:
&lt;a rel="external" href="https://github.com/TypedDevs/bashunit/issues/8">Pregunta: Diferencia con pgrange/bash_unit&lt;/a>.&lt;/p>
&lt;h2 id="como-esta-hoy-en-dia">¿Cómo está hoy en día?
&lt;a class="heading-anchor" href="#como-esta-hoy-en-dia" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Hoy, puedes &lt;a rel="external" href="https://bashunit.typeddevs.com/installation">instalar&lt;/a> bashunit via curl, Homebrew, MacPorts, descargando el último &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/releases">release de GitHub&lt;/a>, o incluso &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/blob/main/build.sh">compilándolo tú mismo&lt;/a> desde el código fuente. Completamente open-source.&lt;/p>
&lt;p>El proyecto está escrito en Bash 3.2 (de 2007) ya que esa es la versión por defecto en macOS, incluso ahora, en 2024. Esta compatibilidad significa que bashunit funciona sin problemas en esa versión, y planeo mantener el soporte para ella.&lt;/p>
&lt;p>Para asegurar la calidad, probamos cada característica con tests unitarios, funcionales y de aceptación, haciendo que bashunit sea su propio “primer usuario” de cada nueva característica. También tenemos varios workflows de CI usando &lt;a rel="external" href="https://github.com/TypedDevs/bashunit/actions/workflows/tests.yml">GitHub actions&lt;/a> que ejecutan tests en diferentes plataformas para verificar compatibilidad y confirmar que todo funciona como se promete.&lt;/p>
&lt;p>&lt;img src="/images/blog/2024-10-30/bashunit-ci.jpg" alt="bashunit-ci.jpg" />&lt;/p>
&lt;p>En junio de 2024, bashunit fue &lt;a rel="external" href="https://bashunit.typeddevs.com/blog/2024-06-21-phpstan-integration">integrado en PHPStan&lt;/a> para sus tests end-to-end, permitiendo el uso de las assertions de bashunit independientemente de su runner. Esta flexibilidad resultó ser muy útil.&lt;/p>
&lt;p>El verano pasado, fui invitado a hablar sobre bashunit en la &lt;a href="/es/talks/#may">International PHP Conference&lt;/a> en Berlín, junto con &lt;a rel="external" href="https://emmanuelvalverde.dev/">Manu&lt;/a>, otro contribuidor. Este proyecto ha abierto puertas y ha llevado a mucha gratitud de usuarios que aprecian el trabajo que hemos puesto en él.&lt;/p>
&lt;h2 id="caracteristicas-principales">Características principales
&lt;a class="heading-anchor" href="#caracteristicas-principales" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>bashunit incluye funciones clásicas del ciclo de vida como &lt;code>set_up&lt;/code>, &lt;code>tear_down&lt;/code>, &lt;code>set_up_before_script&lt;/code> y &lt;code>tear_down_after_script&lt;/code>.&lt;/p>
&lt;p>También soporta una amplia gama de &lt;a rel="external" href="https://bashunit.typeddevs.com/command-line">parámetros de línea de comandos&lt;/a>
y &lt;a rel="external" href="https://bashunit.typeddevs.com/configuration">valores de configuración&lt;/a>. Algunos de mis favoritos incluyen:&lt;/p>
&lt;ul>
&lt;li>&lt;code>--parallel&lt;/code>&lt;/li>
&lt;li>&lt;code>--filter&lt;/code>&lt;/li>
&lt;li>&lt;code>--stop-on-failure&lt;/code>&lt;/li>
&lt;li>&lt;code>--verbose&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>También proporcionamos &lt;a rel="external" href="https://bashunit.typeddevs.com/data-providers">data providers&lt;/a> para ejecutar los mismos casos de test con diferentes inputs.&lt;/p>
&lt;p>Para &lt;a rel="external" href="https://bashunit.typeddevs.com/test-doubles">dobles de test&lt;/a>, bashunit ofrece mocks y spies. Estos funcionan dentro del mismo proceso que el test, pero actualmente no funcionan entre procesos, un área para mejorar.&lt;/p>
&lt;p>Incluye potente &lt;a rel="external" href="https://bashunit.typeddevs.com/snapshots">testing de snapshots&lt;/a>, facilitando la verificación de salidas de comandos o scripts a lo largo del tiempo.&lt;/p>
&lt;p>bashunit ofrece un amplio conjunto de &lt;a rel="external" href="https://bashunit.typeddevs.com/assertions">assertions&lt;/a> nativas para casos de test, incluyendo:&lt;/p>
&lt;ul>
&lt;li>&lt;code>assert_same&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_equals&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_contains&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_matches&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_string_starts_with&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_array_contains&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_successful_code&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_general_error&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_file_exists&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_file_contains&lt;/code>&lt;/li>
&lt;li>&lt;code>assert_match_snapshot&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Incluso puedes crear tus propias &lt;a rel="external" href="https://bashunit.typeddevs.com/custom-asserts">assertions personalizadas&lt;/a> para extender las capacidades de bashunit.&lt;/p>
&lt;p>Con más de &lt;strong>25&lt;/strong> contribuidores y más de &lt;strong>325&lt;/strong> estrellas en GitHub en solo un año de desarrollo en tiempo libre, estoy genuinamente orgulloso de lo que este proyecto se ha convertido.&lt;/p>
&lt;h2 id="lightning-tech-talk">Lightning tech talk
&lt;a class="heading-anchor" href="#lightning-tech-talk" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Recientemente, presenté una lightning tech talk en un meetup de hackers, haciendo una demo de bashunit a una audiencia de más de 100 personas. ¡Fue una experiencia increíble compartir esta herramienta con una audiencia tan comprometida!&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/SX7iNHaSsF0"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;hr />
&lt;p>Logo original de bashunit diseñado por &lt;a rel="external" href="https://antonio.gg/">Antonio&lt;/a>.&lt;/p></content></entry><entry xml:lang="es"><title>Software de Código Abierto</title><subtitle>El poder de contribuir a OSS</subtitle><category term="open-source" scheme="https://chemaclass.com/tags/open-source/" label="Open Source"/><category term="git" scheme="https://chemaclass.com/tags/git/" label="Git"/><category term="career" scheme="https://chemaclass.com/tags/career/" label="Career"/><category term="productivity" scheme="https://chemaclass.com/tags/productivity/" label="Productivity"/><published>2021-05-03T00:00:00+00:00</published><updated>2021-05-03T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/open-source-software/"/><id>https://chemaclass.com/es/blog/open-source-software/</id><summary type="html">Guía práctica sobre software de código abierto: sus beneficios, cómo empezar a contribuir, y por qué compartir código acelera tu crecimiento profesional.</summary><content type="html">&lt;p>Cada proyecto que publicas se apoya en software de código abierto. Tu framework, tu test runner, tu compilador, la pequeña librería en la que nunca piensas.&lt;/p>
&lt;p>Lo usas cada día. La pregunta de verdad es si alguna vez devuelves algo.&lt;/p>
&lt;span id="continue-reading">&lt;/span>
&lt;p>Devolver no es caridad. Es una de las formas más rápidas de crecer como desarrollador.&lt;/p>
&lt;h2 id="que-es-oss">¿Qué es OSS?
&lt;a class="heading-anchor" href="#que-es-oss" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>El código abierto no es lo mismo que el software libre. El software libre es una forma de código abierto, pero el código abierto no tiene por qué ser gratis. Dos ejemplos marcan la línea. &lt;a rel="external" href="https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE">PHPUnit&lt;/a> es código abierto y gratuito. &lt;a rel="external" href="https://github.com/spryker/spryker-core/blob/master/LICENSE">Spryker&lt;/a> es código abierto y de pago. Ambos publican su código para que cualquiera lo lea.&lt;/p>
&lt;blockquote>
&lt;p>OSS es software público, abierto al mundo.&lt;/p>
&lt;/blockquote>
&lt;h2 id="beneficios">Beneficios
&lt;a class="heading-anchor" href="#beneficios" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Dos grupos ganan con el código abierto: las empresas que lo publican, y la gente que contribuye.&lt;/p>
&lt;h3 id="para-empresas">Para empresas
&lt;a class="heading-anchor" href="#para-empresas" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>El acceso abierto impulsa la adopción. Cuanto más fácil es conseguir el código, más rápido construye la gente sobre él. La formación y los tutoriales atraen a los que empiezan y hacen crecer el ecosistema. El código suele estar en la vanguardia, porque el software que se queda quieto se vuelve obsoleto. Un proyecto público reúne una comunidad a su alrededor, y los canales públicos hacen fácil unirse a ella.&lt;/p>
&lt;p>Y como cualquiera puede leer el código, cualquiera puede comprobar su calidad. Esa confianza no se puede fingir.&lt;/p>
&lt;h3 id="para-contribuidores-individuales">Para contribuidores individuales
&lt;a class="heading-anchor" href="#para-contribuidores-individuales" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Tú eliges en qué trabajas. Practicas habilidades reales sin la presión de una caída en producción. Puedes jugar con las últimas novedades de tu lenguaje, o probar un lenguaje que nunca has tocado.&lt;/p>
&lt;p>También afilas las habilidades blandas que sostienen una carrera: escribir con claridad, explicar un cambio, mantener tu postura cuando la gente no está de acuerdo.&lt;/p>
&lt;blockquote>
&lt;p>El código enseña las habilidades técnicas. Los desacuerdos enseñan el resto.&lt;/p>
&lt;/blockquote>
&lt;h2 id="contribuyendo-a-oss">Contribuyendo a OSS
&lt;a class="heading-anchor" href="#contribuyendo-a-oss" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;h3 id="empezando-con-github">Empezando con GitHub
&lt;a class="heading-anchor" href="#empezando-con-github" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Empezar es fácil, y tienes dos puertas. Abrir tu propio proyecto, o contribuir a uno que ya existe. Un proyecto personal encaja perfectamente en la primera puerta.&lt;/p>
&lt;h3 id="proyectos-personales">Proyectos personales
&lt;a class="heading-anchor" href="#proyectos-personales" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Un proyecto personal es un terreno de juego para crear software real y entrenar habilidades reales. Ponlo en tu perfil público de GitHub y tienes todos los beneficios de contribuir a OSS, más uno: no le respondes a nadie. Tú marcas la hoja de ruta. Tú decides qué construir y cómo. Eres tu propio jefe.&lt;/p>
&lt;blockquote>
&lt;p>El proyecto está ahí para ti. Tú eres responsable de jugar, explorar y superar tus límites.&lt;/p>
&lt;/blockquote>
&lt;h3 id="mis-proyectos-personales">Mis proyectos personales
&lt;a class="heading-anchor" href="#mis-proyectos-personales" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>&lt;strong>Activos:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/agnostic-ai">agnostic-ai&lt;/a>: escribe agents, skills, rules y hooks de IA una vez, úsalos en cada CLI de IA.&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/bashdep">bashdep&lt;/a>: un gestor de dependencias sencillo para Bash.&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/phel-snake">phel-snake&lt;/a>: el juego de la serpiente en tu terminal, escrito en Phel.&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/EdifactParser">edifact-parser&lt;/a>: un parser para formato de archivo UN/EDIFACT en PHP.&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/unspent">unspent&lt;/a>: una librería PHP para contabilidad tipo UTXO con entradas no gastadas.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Inactivos:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/create-pr">create-pr&lt;/a>: un script de Bash para abrir un pull request desde tu rama y contexto.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Abandonados:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/stock-ticker">stock-ticker&lt;/a>: recibe una notificación con las noticias de tus Tickers favoritos.&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/JiraStatusNotifier">jira-status-notifier&lt;/a>: notifica cuando los tickets de JIRA no avanzan.&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/php-best-practices">php-best-practices&lt;/a>: lo que consideraba mejores prácticas para desarrollo web (archivado).&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/php-scaffolding">php-scaffolding&lt;/a>: un scaffolding básico de PHP con Docker (archivado).&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/Chemaclass/knob-mvc">knob-mvc&lt;/a>: un framework para crear plantillas WordPress (2015/2017).&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>… y muchos más en &lt;a rel="external" href="https://github.com/Chemaclass">github.com/Chemaclass&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;h3 id="mis-contribuciones-a-organizaciones-oss">Mis contribuciones a organizaciones OSS
&lt;a class="heading-anchor" href="#mis-contribuciones-a-organizaciones-oss" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>&lt;strong>Activas:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://github.com/phel-lang/phel-lang">phel-lang&lt;/a>: Phel es un lenguaje de programación funcional que compila a PHP.
Es un dialecto de Lisp inspirado en Clojure y Janet. Ya escribí un post sobre
esto: &lt;a href="/es/blog/phel-first-release/">Phel: Un Lisp que compila a PHP&lt;/a>&lt;/li>
&lt;li>&lt;a rel="external" href="https://github.com/gacela-project/gacela">gacela-project&lt;/a>: Gacela es un framework PHP que te ayuda a mejorar el
diseño de tu aplicación dividiendo la lógica en diferentes módulos.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Abandonadas:&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://github.com/NuevaMetal/nm_template">nm_template&lt;/a>: La plantilla base para NuevaMetal (2013-2016).&lt;/li>
&lt;/ul>
&lt;h2 id="compartir-conocimiento-e-impacto">Compartir Conocimiento e Impacto
&lt;a class="heading-anchor" href="#compartir-conocimiento-e-impacto" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>El código es solo la mitad. La otra mitad es lo que escribes y le entregas a la siguiente persona.&lt;/p>
&lt;h3 id="posts-del-blog">Posts del blog
&lt;a class="heading-anchor" href="#posts-del-blog" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a href="/es/blog/pull-request-vs-pair-prog/">Pull Requests vs Pair Programming&lt;/a>&lt;/li>
&lt;li>&lt;a href="/es/blog/the-process-itself-is-the-goal/">El proceso en sí es la meta&lt;/a>&lt;/li>
&lt;li>&lt;a href="/es/blog/the-art-of-refactoring/">El arte del refactoring: cuándo, cómo y por qué&lt;/a>&lt;/li>
&lt;li>&lt;a href="/es/blog/the-art-of-testing/">El arte del testing: donde el diseño se encuentra con la calidad&lt;/a>&lt;/li>
&lt;/ul>
&lt;blockquote>
&lt;p>… y muchos más en &lt;a rel="external" href="https://chemaclass.com/es/blog/">https://chemaclass.com/es/blog/&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;h3 id="la-belleza-del-oss">La belleza del OSS
&lt;a class="heading-anchor" href="#la-belleza-del-oss" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;p>Contribuye en público el tiempo suficiente y empiezas a ver tu propio crecimiento. Las correcciones que sigues haciendo. El código que escribiste el año pasado, ya envejecido. Los errores, todos ellos, a la vista. Y por debajo, la prueba lenta de que estás mejorando.&lt;/p>
&lt;p>Vas desarrollando un sexto sentido para detectar patrones que ya has visto, los buenos y los dolorosos.&lt;/p>
&lt;p>&lt;strong>Muestra tus habilidades. Ayuda a la gente a tu alrededor.&lt;/strong> Eso es &lt;a href="/es/blog/working-with-the-garage-door-open/">trabajar con la puerta del garaje abierta&lt;/a>.&lt;/p>
&lt;blockquote>
&lt;p>El Software de Código Abierto te ofrece una de las mejores oportunidades para empezar a construir una carrera hacia la mejora continua.&lt;/p>
&lt;/blockquote>
&lt;hr />
&lt;p>Esta es una charla (en español) que hice de forma remota en abril de 2021,
para la &lt;a rel="external" href="https://www.meetup.com/phpmad/events/277733306/">Comunidad PHPMad Madrid&lt;/a>. Presento todas estas ideas
junto con una demo en vivo de cómo contribuir a un OSS real.&lt;/p>
&lt;div style="position:relative;aspect-ratio:16/9;width:100%;">
&lt;iframe
src="https://www.youtube-nocookie.com/embed/GE5wR_SC_P4"
title="YouTube video"
width="560"
height="315"
loading="lazy"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
referrerpolicy="strict-origin-when-cross-origin"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allowfullscreen>
&lt;/iframe>
&lt;/div>
&lt;hr /></content></entry><entry xml:lang="es"><title>Phel: el Lisp que Compila a PHP</title><subtitle>Un nuevo lenguaje funcional con interoperabilidad total con PHP</subtitle><category term="phel" scheme="https://chemaclass.com/tags/phel/" label="Phel"/><category term="php" scheme="https://chemaclass.com/tags/php/" label="Php"/><category term="open-source" scheme="https://chemaclass.com/tags/open-source/" label="Open Source"/><category term="software-design" scheme="https://chemaclass.com/tags/software-design/" label="Software Design"/><published>2021-02-01T00:00:00+00:00</published><updated>2021-02-01T00:00:00+00:00</updated><author><name>
Chemaclass</name></author><link rel="alternate" type="text/html" href="https://chemaclass.com/es/blog/phel-first-release/"/><id>https://chemaclass.com/es/blog/phel-first-release/</id><summary type="html">El nuevo lenguaje de Programación Funcional construido para PHP.</summary><content type="html">&lt;p>Un nuevo lenguaje de Programación Funcional construido sobre el ecosistema de PHP.&lt;/p>
&lt;span id="continue-reading">&lt;/span>&lt;h2 id="el-lenguaje-phel">El Lenguaje Phel
&lt;a class="heading-anchor" href="#el-lenguaje-phel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Phel es un lenguaje de Programación Funcional (&lt;a rel="external" href="https://en.wikipedia.org/wiki/Functional_programming">FP&lt;/a>) que compila a PHP. Es un dialecto de &lt;a rel="external" href="https://en.wikipedia.org/wiki/Lisp_(programming_language)">Lisp&lt;/a> inspirado en Clojure y Janet.&lt;/p>
&lt;h2 id="caracteristicas">Características
&lt;a class="heading-anchor" href="#caracteristicas" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>Construido sobre el ecosistema de PHP&lt;/li>
&lt;li>Buenos reportes de errores&lt;/li>
&lt;li>Diferentes estructuras de datos (Arrays, Tables y Tuples)&lt;/li>
&lt;li>Macros&lt;/li>
&lt;li>Funciones recursivas&lt;/li>
&lt;li>Sintaxis potente pero simple&lt;/li>
&lt;li>REPL&lt;/li>
&lt;/ul>
&lt;h2 id="por-que-phel">¿Por qué Phel?
&lt;a class="heading-anchor" href="#por-que-phel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>Phel lo creó Jens Haase. Como menciona en el sitio web, “es el resultado de muchos &lt;a rel="external" href="https://phel-lang.org/blog/functional-programming-in-php">intentos fallidos de hacer programación funcional en PHP&lt;/a>”. Buscaba algo con estas características:&lt;/p>
&lt;ul>
&lt;li>Inspirado en LISP&lt;/li>
&lt;li>Lenguaje de Programación Funcional&lt;/li>
&lt;li>Que funcione en proveedores de hosting baratos&lt;/li>
&lt;li>Sea fácil de escribir y depurar&lt;/li>
&lt;/ul>
&lt;p>A finales de mayo de 2020 terminé el libro &lt;a href="/es/readings/7-languages-in-7-weeks/">Seven Languages in Seven Weeks&lt;/a>, donde aprendí los fundamentos de Prolog, Erlang, Clojure, Haskell… Incluso creé un &lt;a rel="external" href="https://github.com/Chemaclass/7LangIn7Weeks">repositorio en GitHub&lt;/a> para guardar mi progreso.&lt;/p>
&lt;p>A principios de junio de 2020, vi un post en el canal de PHP de Reddit mencionando este proyecto “&lt;strong>Phel&lt;/strong>”: un &lt;strong>lenguaje de programación funcional escrito en PHP&lt;/strong>.&lt;/p>
&lt;p>Llevo unos 8 años trabajando con PHP, y siempre intento combinar OOP con FP (creo que ambos paradigmas funcionan mejor juntos; no son excluyentes). Un nuevo dialecto de Lisp escrito en &lt;strong>PHP 7.4&lt;/strong> nativo sonaba emocionante. Decidí echarle un vistazo al código.&lt;/p>
&lt;p>Las lecturas recientes de &lt;a rel="external" href="https://x.com/matthiasnoback">Mathias NoBack&lt;/a>, como &lt;a href="/es/readings/object-design-style-guide">Object Design Style Guide&lt;/a> y &lt;a href="/es/readings/advance-web-application-architecture/">Advanced Web Application Architecture&lt;/a>, me dieron el empuje para aplicar lo aprendido en un proyecto real. Este fue (y sigue siendo) un desafío que me ayuda a crecer profesionalmente.&lt;/p>
&lt;p>Mi primer commit fue el 6 de junio de 2020. Desde entonces dedico un poco de tiempo cada día en mis horas libres.
Me ayuda a aprender sobre FP, diseño interno de lenguajes, testing y arquitectura de software en general.&lt;/p>
&lt;p>Empecé con cambios menores hasta que acabé refactorizando toda la estructura del compilador para hacer los módulos más legibles. Psalm, tipos estrictos, buena cobertura de tests, estilo de código unificado… Estos fueron algunos de mis temas favoritos.&lt;/p>
&lt;h2 id="ejemplo-de-codigo-phel">Ejemplo de código Phel
&lt;a class="heading-anchor" href="#ejemplo-de-codigo-phel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;p>El siguiente ejemplo da una breve impresión de cómo se ve Phel:&lt;/p>
&lt;pre class="giallo" style="color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);">&lt;code data-lang="plain">&lt;span class="giallo-l">&lt;span># Define un namespace&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>(ns my\example)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span># Define una variable con nombre &amp;quot;my-name&amp;quot; y valor &amp;quot;world&amp;quot;&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>(def my-name &amp;quot;world&amp;quot;)&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span># Define una función con nombre &amp;quot;print-name&amp;quot; y un argumento&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>(defn print-name [your-name]&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span> (print &amp;quot;hello&amp;quot; your-name))&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span># Llama a la función&lt;/span>&lt;/span>
&lt;span class="giallo-l">&lt;span>(print-name my-name)&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;h2 id="estado-actual-de-phel">Estado actual de Phel
&lt;a class="heading-anchor" href="#estado-actual-de-phel" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h2>
&lt;ul>
&lt;li>Preparamos una fácil &lt;a rel="external" href="https://phel-lang.org/documentation/getting-started/">Guía de Inicio&lt;/a>&lt;/li>
&lt;li>Preparamos un Repositorio GitHub fácil con una &lt;a rel="external" href="https://github.com/phel-lang/phel-scaffolding">Plantilla de Scaffolding de Phel&lt;/a>&lt;/li>
&lt;li>Acabamos de lanzar la primera versión oficial: &lt;a rel="external" href="https://github.com/phel-lang/phel-lang/tags">0.1.0&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>Consulta el sitio web oficial con toda la documentación: &lt;a rel="external" href="https://phel-lang.org/">https://phel-lang.org/&lt;/a>&lt;/p>
&lt;hr />
&lt;h3 id="tambien-recomendado">También recomendado
&lt;a class="heading-anchor" href="#tambien-recomendado" title="Copy link" aria-label="Link to this section">#&lt;/a>
&lt;/h3>
&lt;ul>
&lt;li>&lt;a rel="external" href="https://jesusvalera.dev/functional-programming-with-phel/">Functional Programming with Phel - JesusValera&lt;/a>&lt;/li>
&lt;/ul></content></entry></feed>