2025/05/14

GitHub CMS 101

 akobashikawa/github-cms-101: A simple CMS (Content Management System) that uses GitHub's infrastructure for deployment and publishing.


https://github.com/akobashikawa/github-cms-101

2024/08/18

WordStar en Windows 10



Recientemente, Robert J. Sawyer, el reconocido escritor de ciencia ficción, publicó que escribía sus novelas usando WordStar, el mejor procesador de textos que haya conocido.

No es el único que opina igual, también se cuenta entre sus usuarios a Anne Rice, autora de “Entrevista con el Vampiro” y George R. R. Martin, autor de “Juego de Tronos”.

Y eso que WordStar es abandonware. Es decir, software muy antiguo que ha dejado de mantenerse e incluso de distribuirse de manera oficial.

Las copias que circulan por ahí se debe a una comunidad de usuarios entusiastas. Como Robert J. Sawyer.

Tampoco corre ya en los sistemas operativos modernos, a menos que se haga uso de algún emulador.

En su página sobre el tema, Science Fiction Writer Robert J. Sawyer: WordStar 7 Archive, cuenta más al respecto y facilita el procedimiento para hacer lo mismo.

C:\
cd WS
ws
  • El montaje del drive se tendría que hacer cada vez que se ingresa a DOSBox-X. Pero se puede automatizar, agregando en el archivo de configuración dosbox-x.conf una línea como:
mount C: C:\dos-c

2022/07/04

Cómo usar docx2html en angular


¿Quieres usar este procesador de documentos word en Angular? Te cuento el procedimiento que seguí y me funcionó. 

Cómo usar docx2html en Angular

2022/06/26

Cómo forzar el idioma de Jenkins a Inglés



¿Quieres forzar a que Jenkins use inglés para seguir mejor la documentación? Te cuento el procedimiento que seguí.

Cómo forzar el idioma de Jenkins a Inglés 

2022/06/24

Cómo instalar Jenkins en Windows



¿Quieres instalar este poderoso servidor de automatizaciones en una máquina windows? Te cuento el procedimiento que seguí y me funcionó tanto en Windows Server 2019. Para Windows 10 Home Edition fue necesario hacer un parche previo.

Cómo instalar Jenkins en Windows 

2022/03/12

Link hacia Whatsapp

 


¿Quieres crear un link que abra un chat en Whatsapp? Te cuento cómo lo solucioné con HTML.

  • Lo que necesitaba era que en el whatsapp del usuario se abriera un chat hacia cierto número y con un texto prestablecido.
  • Encontré que debía formar un url con un formato similar a https://api.whatsapp.com/send?phone=51999888777&text=Hola
    • El número de teléfono indicado por phone debe incluir el código del país (51 en este ejemplo)
    • El texto indicado por text debe ser url compatible, es decir que se pueda indicar a través del url.
      • Puedes usar una herramienta como URLEncoder para convertir tu texto. Incluso puedes poner emojis! 🙂
      • Si usas javascript para generar el enlace, la función encodeURI hace el trabajo.
  • De ese modo, es posible formar un enlace como este:
<a href="https://api.whatsapp.com/send?phone=51999888777&text=Hola%21%20%F0%9F%91%8D%F0%9F%99%82">Saludar por Whatsapp</a>
  • Cuando el usuario hace clic en el enlace, le aparece un diálogo para permitirle ir a la app whatsapp (si está instalada), donde abrirá el chat correspondiente al número indicado y con el texto indicado pre llenado.

¿Conoces otro modo de hacer esto, o quizás de manera más sencilla? Puedes compartirlo en los comentarios 🙏


Publicado originalmente en AKC Puroguramu

Solución al Vue Router y Vuex descontinuados para Vue2

 


¿Tienes alguna aplicación vue2 que ha dejado de funcionar de pronto? Te cuento cómo solucioné la incompatibilidad que se presentó para vue-router y vuex.

  • Hoy noté que una de las aplicaciones que desarrollé con vue2 estaba caída 🙈.
    • Revisando la consola, noté que no encontraba https://unpkg.com/vue-router@4.0.14/dist/vue-router.js.
    • Ese era el destino final que correspondería al que le indicaba en mi código: //unpkg.com/vue-router/dist/vue-router.js.
      • Cuando se indica así te lleva a la última versión, que al parecer ya no es más vue2 compatible.
  • Al parecer, la versión 4 de vue-router se ha vuelto vue3 compatible por default, así que hay que indicar explícitamente la versión vue2 compatible que uno quiere usar.
  • Pasé a indicar la versión 3 de vue-router y ya funcionó esa parte
    • De //unpkg.com/vue-router/dist/vue-router.js a //unpkg.com/vue-router@3. 👍🙂
  • Luego pase a resolver el issue similar para el caso de vuex.
    • Allí, también tuve tuve que indicar explícitamente la versión vue2 compatible (casualmente también es la 3)
      • De //unpkg.com/vuex a //unpkg.com/vuex@3.
  • En mi caso, estos dos cambios fueron suficientes para que la aplicación volviera a estar operativa. ✌️🙂

¿Has encontrado alguna versión más reciente de estos paquetes que sea vue2 compatible? Puedes compartirlo en los comentarios 🙏


Publicado originalmente en AKC Puroguramu

Hugo: Tips para publicar un post con un video de youtube



  • Uso Hugo, con el tema LoveIt, para publicar un blog como este.
  • Para mostrar un video se puede usar el shortcode youtube
{{< youtube XaKhz3iAxqQ >}}
  • Para obtener una featured imagen para el post del video, se puede usar # Get YouTube Video Thumbnail Image
    • Requiere el url del video
  • Para mostrar la feature image en el listado del home pero no dentro del post (ya que el video ya lo tiene), se puede usar en el front matter featuredImagePreview en lugar de featuredImage


Publicado originalmente en AKC Puroguramu

2021/03/21

Reflexiones sobre la autoeficacia




Hay un concepto que me parece interesante. Autoeficacia. Es la creencia de uno mismo de ser capaz de realizar algo.

Si lo has hecho muchas veces antes, es prácticamente del 100%. O si has hecho algo parecido. O si has visto que lo han conseguido antes personas con las que te identificas, como familares o amigos.

Esto explica por qué muchos eligen en la vida la misma profesión que sus familiares o amigos, o gente cercana de su comunidad. Porque su ejemplo de éxito les da un mayor nivel de autoeficacia para andar ese mismo camino.

Si es tu primera vez enfrentando algo que tiene muchos aspectos desconocidos, quizás sientas un nivel de autoeficacia muy bajo o de 0%.

Aunque no necesariamente. Los emprendedores, por ejemplo, pueden sentir una autoeficacia muy alta o de 100% aún cuando no tengan ninguna certeza del camino que están tomando o de las cosas que les tocará hacer. Simplemente confían en que serán capaces de sortear las dificultades que aparezcan, cuando aparezcan, si es que aparecen, aunque no sepan de antemano cuáles serán.

Tener un alto nivel de autoeficacia es algo muy positivo a la hora de enfrentar un problema.

Sentir que puedes hacerlo, aunque ahora no sepas exactamente cómo, es un gran super poder.

Pienso que se apoya en tus experiencias exitosas enfrentando lo desconocido. Si siempre has ido a la segura, por caminos pautados, probablemente te cueste más. O también si has tenido experiencias desafortunadas al respecto.

Cuando sientes un nivel bajo de autoeficacia, puedes tender a procrastinar; a entretenerte haciendo otras cosas. A otros esto le puede parecer inútil, perezoso o evasivo, pero en realidad indica que estás buscando formas de sentir la autoeficacia que te está faltando. Logros que alcances en un juego, o ver cómo otros logran algo, o evocar logros pasados, o imaginarlos en el futuro, etc. Básicamente, estas tratando de visualizar que puedes.

El empeño en alcanzar la perfección también sería una búsqueda de sentir mayor autoeficacia. Pero el perfeccionista cae en la trampa de confundir la herramienta con la solución. Y en el afan de tener todo perfecto como requisito para hacer cualquier cosa.

Haciendo cosas, y resolviendo problemas con un inventario imperfecto es que la autoeficacia se fortalece.

Cuando navegas en la red, ves mucha búsqueda de estar preparado, de dominar algo, de tener el mejor inventario de habilidades posible, las mejores herramientas.

Tener el mejor martillo no es el problema, sino lo que podamos construir usando ese martillo. Tener el mejor martillo seguramente ayudaría, pero es importante tener claro cuál es la herramienta y cuál lo que queremos construir.

Cuál es el mejor lenguaje de programación? Tal vez éste lo sea. Y el mejor framework?. Quizás esté otro. Y la persona con el mejor curriculum? A lo mejor esta. Resulta que la mayoria de veces, nos dedicamos más a tener perfectos esos detalles, porque buscamos aumentar nuestro nivel de autoeficacia. Pero si distinguimos que son herramientas para conseguir solucionar algo, entonces tendremos más comprensión de la realidad, más tolerancia cuando las dificultades no se inclinen ante nuestras habilidades, y más tolerancia a nuestras imperfecciones y a las de los demás. Sobre todo cuando alguien "menos perfecto" usando las herramientas "menos perfectas" es quien logra solucionar los problemas con éxito.

2019/11/07

Nodemon indica puerto ocupado: una solución

Usando nodemon en express:

package.json
  ...
  "scripts": {
    "start": "node ./bin/www",
    "dev": "nodemon ./bin/www"
  },
  ...

A veces me pasa que indica que el puerto ya está ocupado. Entonces, procedo a matar el proceso para comenzar otra vez.

$ lsof -i:3000
$ kill 1234
$ npm run dev

Donde 3000 sería el puerto y 1234 el PID del proceso.

Una forma de aliviar la molestia:

$ kill $(lsof -i:3000 -t); npm run dev


Otra forma es usar kill-port y un delay.

$ npm install --save-dev kill-port

package.json
  ...
  "scripts": {
    "start": "node ./bin/www",
    "dev": "kill-port 3000 && nodemon --delay 1 ./bin/www"
  },
  ...

2019/09/29

Vue Simple App: Sin webpack

Vue, Router, Vuex y Vuetify, pero sin webpack

[Actualizado el 2019/11/05: "Carga dinámica"]

Tal vez no tenga ninguna razón técnica importante para preferir prescindir de webpack al desarrollar una aplicación web.

Tal vez sea solamente nostalgia por los viejos tiempos, donde simplemente importabas librerías en la página y la magia podía aparecer.

Tal vez no sea mala idea tener esa capa extra que cargar en el viaje, y aceptarla a cambio de los caramelos que nos regala.

Pero a mi me molesta un poco.

Preferiría no tener que usarla si puedo evitarlo.

Siento que hay que tener cuidado cuando algo aumenta la complejidad. Mayor velocidad o comodidad pueden ser justificaciones. Pero hay que estar atentos a no limitar la diversidad de opciones.

Una de las cosas que me gusta de Vue es que puedo empezar muy simple, importando la librería en la página. Y luego, si el problema lo amerita, ir escalando la solución hacia algo más y más complejo. Es como empezar descalzo si quiero, o con sandalias, e ir cambiando según lo amerite el terreno.

La mayoría de tutoriales parece estar de acuerdo en que usar vue create es la opción más práctica. Sin embargo, algo que descubrí es que también se puede llegar a elaborar soluciones relativamente complejas sin usar un transpilador.

Esta es una guía en un proceso de desarrollo simple que nos permita usar Vue, Router, Vuex y Vuetify, sin necesitar la complejidad extra de webpack.

HTML5

Un lugar simple donde empezar.

HTML5: https://codepen.io/akobashikawa/pen/NWKVazJ

HTML5 + Vue

Importar vue y desarrollar un script en la misma página.

HTML5 + Vue: https://codepen.io/akobashikawa/pen/aborLgW

HTML5 + Vue + Router

Importar Vue Router para organizar la navegación.

Eso también nos empuja a organizar el contenido en componentes, si es que no lo hemos hecho ya.
HTML5 + Vue + Router: https://codepen.io/akobashikawa/pen/qBWGVEp

HTML5 + Vue + Router + Vuex

Importar Vuex para compartir un estado general entre los componentes.
HTML5 + Vue + Router + Vuex: https://codepen.io/akobashikawa/pen/pozmdby

HTML5 + Vue + Router + Vuex + Vuetify

Para darle un look de app con Material Design.

HTML5 + Vue + Router + Vuex + Vuetify: https://codepen.io/akobashikawa/pen/bGbyYod

Módulos

Cuando más componentes van apareciendo y el largo del archivo va haciendo complicada la edición, parece una señal para sacar el código javascript a otro archivo.

Javascript soporta import. Pero hay que usarla dentro de un módulo.

Algo que ocurre con los módulos declarados normalmente, es que se carga toda la estructura de dependencias desde el inicio.

Para prevenirlo, y que cada módulo se pueda cargar cuando se necesita y no antes, se puede usar la técnica de declarar el componente como resultado de una función:

Antes:
import Counter from './Counter.js';
Después:
const Counter = () => import('./Counter.js');

Conclusión

Es posible desarrollar vue apps de relativa complejidad sin necesidad de usar webpack.

Me parece que este esquema puede simplificar el inicio de un proyecto. Aún cuando la versión para producción pueda requerir webpack para las optimizaciones, se podría usar esto durante el desarrollo.

¿Qué ventajas o desventajas ves hacerlo de este modo?, ¿te parece que puede facilitar la depuración?, ¿crees que en el futuro los navegadores carguen los scripts de un modo que no sea necesario empaquetarlos como actualmente?

2019/09/27

Ajedrez Mental

A menudo hay profesionales que discuten y resuelven problemas simplemente hablando. Incluso problemas muy complejos. Sin apoyarse en anotar algo en el papel o la pizarra que está a su lado.

Tal vez se vea un símbolo de status profesional. Un aviso de que somos lo suficientemente expertos para prescindir de esas herramientas.

Pero, de vez en cuando, te encuentras con alguien que sí las aprovecha y el resultado es notable.

Me parece que intentar resolver un problema solamente hablando es como jugar ajedrez mentalmente. Puede ser impresionante como show, pero tiene algunas desventajas para considerar:
  • Además de la tarea de buscar la mejor jugada, se gasta energia mental en mantener una imagen compartida del tablero.
    • Es más fácil que pierdas de vista una pieza
    • Es más difícil evaluar una posicion
    • Es más difícil explorar algo complejo, o arriesgado, o de mucha profundidad
  • Al no haber algo tangible, es más vulnerable a las relaciones de poder de los participantes
    • Es más fácil ceder ante el experto que insistir en tu punto de vista, aunque sientas que el experto está equivocado
    • Es difícil que alguien se anime a decirle al campeón que la posición de las piezas no es la que el dice
    • Hay expertos o campeones que pueden usar esto para intentar atarantar a quienes tienen menos poder

En cambio, al usar papel o una pizarra es como jugar ajedrez con un tablero físico
  • Visible para todos
    • Cualquiera que pase puede verlo y darse una idea de la situación
    • Es más fácil ver las piezas
  • Tienes más energía mental disponible
    • Es más fácil evaluar una posición
    • Es más fácil descubrir algo que no esperabas
    • Puedes explorar variantes más complejas o arriegadas
  • Puedes anotar las partidas y revisarlas luego
    • Aprender
    • Explorar variantes
  • Es menos vulnerable a las relaciones de poder
    • Con una prueba evidente, es más fácil rebatir a un experto o campeón que se haya equivocado

Pienso que usar anotaciones para apoyar una conversación o una explicación debería ser la regla y no la excepción.

Quizás habría que estar atento cuando alguien que pudiendo usar anotaciones no lo hace. Podría estar tratando de ocultar algo.

2019/09/14

Sobre desarrollo de software


La administración de la energía creativa sería la clave para un proyecto exitoso

Desarrollar software es un proceso que se viene descubriendo.

Hay quienes han intentado amoldarlo a un esquema como el que se sigue en la ingeniería o la arquitectura. Parece funcionar en algunos casos, pero no ha resultado satisfactorio siempre.

Aún hoy, décadas después de creada la ingeniería de software o las ciencias de la computación, a veces no es claro por qué un proyecto de desarrollo que parece bueno fracasa. O por qué uno que parece absurdo temina triunfando sobre todas las demás opciones.

Algo que hay que tener en cuenta es que el software no solamente debe correr en la computadora, sino en el sistema determinado por las personas que lo usen.

La ingeniería de software y las ciencias de la computación suelen concentrarse en cómo crear algoritmos que corran eficientemente en una computadora. La UX, o experiencia de usuario, se concentra en cómo sintonizar con las necesidades reales de las personas que usarán la solución que se desarrolla.

Desarrollar software no es como realizar una tarea, donde cada paso es sobre terreno conocido. Es más como resolver un problema. Es decir, es como avanzar por una curva cuyo curso no es evidente. Hay que recurrir a la experiencia pero también a la intuición. Como cuando se hace arte.

Me parece que la mejor manera de desarrollar software es iterádamente, iniciando con una base muy simple y luego ir evolucionando para alcanzar lo que se requiere.

Esto requiere un proceso de desarrollo que sea sostenible y escalable. Sostenible significa que se pueda repetir una y otra vez el ciclo de mejora. Escalable significa que puede soportar el siguiente estado de evolución del producto.

Muchos desarrolladores se preocupan mucho por si el producto es escalable. De si podrá soportar diez veces más usuarios, o cien veces más datos. Creo que más importante que la escalabilidad del producto es la escalabilidad del proceso para desarrollar el producto.

Creo que la razón principal por la que los proyectos de desarrollo de software a menudo fracasan es porque no logran formar un proceso de desarrollo escalable. Suelen usar un esquema de producción en línea, como en una fábrica donde cada pieza es conocida, en lugar de espiral, como en un laboratorio donde cada pieza se está ensayando sobre un diseño que se va descubriendo. Conforme la complejidad aumenta, distintas partes del proyecto van cayendo bajo su propio peso, hasta que todo colapsa. O sigue adelante con montones de parches y apuntalamientos de emergencia que hacen que no sea posible continuar con su evolución de manera clara.

Quizás esto se pueda ver mejor considerando que existe una energía creativa. Es la energía con la que se cuenta para convertir una idea en un producto de software.

Mientras no se llega a  un un producto concreto, la energía creativa va disminuyendo. Es como cuando un móvil se va empujando. Para que gane altura o gane velocidad, hay que gastar energía empujándolo contra la gravedad o la fricción. Cuanto más largo es el salto, más fuerza, velocidad y energía se requieren.

Pero cada vez que se llega a un producto concreto, ganamos un nuevo punto de apoyo para dar el siguiente paso desde allí. Esta energía permite ir por una siguiente versión. Es más fácil, y más sostenible, llegar al quinto escalón desde el cuarto que desde el primero.

Podemos ilustrar esto imaginando que el proyecto es como llevar una bola de nieve cuesta arriba. Al inicio, reunimos nieve de aquí y de acá y empezamos a rodar esa bola inicial fácilmente. Conforme la bola crece, va requiriendo más energía. Entonces llegamos a una pequeña meseta. Eso nos permite recuperar energía, apreciar lo que hemos recorrido y ver mejor cómo continuar. Luego seguimos subiendo, gastando energía hasta que lleguemos a la siguiente meseta, donde nos recuperamos. En el viaje, vamos decidiendo si necesitamos ayuda de más personas para seguir empujando la bola, despejando el camino, apuntalando, etc. Cada vez requerirá más energía poder avanzar y llegar a una meseta segura. Puede ser que esa meseta sea la cima, y el proyecto llegue así a buen término. Puede ser que no sea la cima pero una meseta cercana y aceptable. O puede ser que no se encontró una meseta a tiempo y, sin un apoyo adecuado ni energía para continuar, la bola se tuvo que soltar, yéndose cuesta abajo.

Versionado frecuente. Una buena estrategia es tener mesetas frecuentes. Es decir, sacar versiones completamente funcionales frecuentemente. No importa si es un paso corto si podemos continuar andando. Los pasos acrobáticos son un lujo que puede no ser sostenible. Los periodos de desarrollo largos que no concretan van consumiendo la energía riesgosamente.

Ir ligero (LEAN). Otra buena estrategia es mantener la bola en un tamaño manejable. Es decir, ir dejando atrás aquello que ya no es necesario para que siempre podamos avanzar con los recursos que tenemos.

Dividir y vencer. Otra buena estrategia es dividir el trabajo en varias bolas que lleguen a la cima. Es decir, poder separar el proyecto en partes independientes y fáciles de manejar que puedan ser conectadas luego.

Testing (TDD). Otra buena estrategia es apuntalar el avance de la bola. Es decir, contar con pruebas de código o de flujo que validen el estado del proyecto. Se pueden poner luego de que la bola ya alcanzó cierta posición pero suele ser mejor estrategia ponerlas primero y luego mover la bola hacia allí.

Sinergia. Otra buena estrategia es rodar armoniosamente la bola. Es decir, que cada persona del equipo sintonice con el propósito del proyecto, y tenga la autonomía que le permita usar sus habilidades con maestría para colaborar en su realización.

La trampa del perfeccionismo. Una estrategia no muy buena es querer empezar con un montón de nieve demasiado grande. Es decir, requerimientos iniciales demasiado complejos, por número o por dificultad. Son más firmes las bolas de nieve que van creciendo y haciéndose redondas por su propio rodar. A menudo, querer empezar con algo que parezca perfecto para impresionar a los demás suele conducir a parálisis por análisis: el proyecto empieza a procrastinar, la energía creativa se diluye, y finalmente no despega.

La trampa de la temeridad. Otra estrategia no muy buena es ignorar la ayuda de apuntalamientos y confiar únicamente en el propio esfuerzo para mantener la bola en curso. Es decir, no tener pruebas que permitan verificar que se está donde se debe estar. Implementar pruebas requiere algo de energía creativa, pero luego permite ahorrar mucha más.

La trampa de la insensibilidad. Otra estrategia no muy buena es ignorar que quienes ruedan la bola son personas. Es decir, se cae en tentación de creer que bastan las herramientas, las técnicas o la infraestructura, o la capacidad de hacer algo, para que ese algo se pueda realizar, ignorando que hay un aspecto social, con una voz que debe ser escuchada y honrada. Hay redes de confianza que deben ser tejidas y mantenidas, para que las personas puedan realizarlo.
Hay proyectos con pendientes de dificultad muy llevaderos, donde parece que se puede ir con facilidad hacia cualquier dirección y se llega a la cima de un modo predecible.

Hay otros proyectos donde el terreno no es parejo, la nieve es irregular y sopla la ventisca.

Llevar exitosamente la bola de nieve a la cima no depende solamente de cuánta gente la empuja ni cuánta fuerza tenga. Depende de ser capaz de llegar oportunamente a las mesetas adecuadas. Es entender el terreno, el clima, la nieve, la gente, su fuerza, sus habilidades, y poder manejar todo eso.




2019/01/11

2018/12/31

Hello Jenkins: Como root

En el post Hello Jenkins, exploré cómo podría automatizar el deploy de un site estático simple con ayuda de Jenkins.

Este site estático está alojado en mi directorio web personal ~/public_html. Para que Jenkins pudiera hacer pull allí, fue necesario que tuviera derechos sobre los archivos de ese directorio, así que opté por agregarlo a mi grupo de usuario.

Ahora exploro cómo sería si quisiera que Jenkins pudiera hacer pull en el directorio web /var/www.

En mi Jenkins, proyecto hello-jenkins, Configuration, Source Code Management:

  • En Aditional Behaviours, pruebo agregar:
    • Chek out to a sub-directory
      • Local sub-directory for repo:
        /var/www/html/demos/hello-jenkins/
Una prueba muestra un error de acceso al directorio. Probé agregar jenkins al grupo sudo y tambien visudo, pero no pude solucionarlo.

Opto por agregar el siguiente script en Build:
  • echo "hello-jenkins build"
  • cd /var/www/html/demos/hello-jenkins
  • sudo git pull
Hago la prueba y funciona como se espera. Se hace pull al hello-jenkins en mi directorio personal public_html/ y tambien en el directorio web /var/www/.


2018/12/30

Hello Jenkins


En días recientes estuve viendo un poco de Continuous Integration / Continuous Deployment (CI/CD), con Jenkins.

La idea que he captado es que Jenkins corre en el servidor donde normalmente ejecutamos a mano los pasos para deployar un proyecto. Luego configuramos las cosas para que Jenkins las haga por nosotros.

Por ejemplo, puedo tener en mi hosting un site estático hello-jenkins, cuyo repositorio está en GitHub. Luego que hago push en el repo desde mi máquina local debo entrar a la consola de mi hosting y hacer pull. Quizás alguna cosa más, como bower o npm, dependiendo de la complejidad del proyecto.

Empezaré con un simple site estático llamado hello-jenkins.

Ahora, haré un cambio y un deploy manual.
  • En mi local, agrego un title, commit y push
  • En mi hosting, hago pull
    • Lo pesado de esta tarea es cuando no estoy logueado a la consola. Es necesario hacer ssh, ubicar la carpeta y hacer pull.
    • Si Jenkins vive en este servidor, podría hacerlo por mi ante una señal. Por ejemplo, cuando se hace un push en GitHub.
  • https://rulokoba.me/~rulo/demos/hello-jenkins/
En el hosting, tengo instalado Jenkins siguiendo la guía de:
En mi Jenkins, creo el job hello-jenkins:
  • Elijo create new jobs
  • Enter an item name: hello-jenkins
  • Elijo Freestyle project
  • OK
  • En la sección de consiguración:
    • Source Code Management
      • Git
        • Repository URL: https://github.com/akobashikawa/hello-jenkins.git
        • Credentials: none
        • Additional Behaviours
          • Check out to a sub-directory
            • Local sub-directory for repo:
              /home/rulo/public_html/demos/hello-jenkins/
            • Para que jenkins pueda escribir en este directorio se le puede agregar al grupo del usuario y reiniciar jenkins:
              • $ sudo usermod -a -G rulo jenkins
              • $ sudo systemctl stop jenkins
              • $ sudo systemctl start jenkins
    • Build Triggers
      • GitHub hook trigger for GITScm polling
    • Build (opcional)
      • Execute shell
        • Command
          • echo "hello-jenkins build"
En el repo de GitHub, Settings:
  • Webhooks
    • Add webhook
      • Payload URL: http://myjenkins_url/github-webhook/
        • Es importante el trailing / al final
      • Content type: application/json
      • Which events would you like to trigger this webhook?
        • [x] Let me select individual events.
          • [x] Pushes
            • [x] Pull requests
      • [x] Active
      • Add webhook
      • Es importante que GitHub pueda encontrar a Jenkins ya configurado
Para probar, manualmente:
  • En mi Jenkins, en el projecto hello-jenkins, wlijo Build Now
  • En Build History aparecerá un nuevo item numerado, y le hago click.
  • Elijo Console Output para ver la salida
Para probar el build automático:
  • En mi local, hago un cambio, commit y push al repo
  • En Build History aparecerá un nuevo item numerado, y le hago click.
  • Elijo Console Output para ver la salida

2018/09/18

Solucionando conexión de strapi a mLab



Strapi es un framework para node que facilita la creación de un cms.
  • Como base de datos puede usar mongo, mysql, postgres.
  • Como frontend puede usar vue, react, angular.
  • El panel de administración luce bastante similar al de wordpress.
  • Tiene un plugin para servir los datos con graphql.
  • El idioma se puede configurar a español.
mLab es un servicio que provee acceso a bases de datos mongo.
  • Tiene una capa de uso gratuita (via AWS de Amazon)

Instalación simple

  • Para usarlo con mongo, debe estar iniciado el servicio localmente
  • $ node --version
    • Se requiere al menos la versión 9
  • $ npm install -g strapi@alpha
    • Por alguna razón, recomiendan que trabajemos con la versión más fresca
  • $ strapi --version
    • Actualmente 3.0.0-alpha.14.1.1
  • $ strapi new myapp
    • Creará la estructura de directorios.
    • Hay que elegir como base de datos a mongo e indicar los parámetros
      • Esta data se guarda en myapp/config/environments/development/database.json
      • La base de datos aún no se crea en este punto
  • $ cd myapp
  • $ strapi start

Problema con mongo externo

Por alguna razón, cuando se indica que se conecte a una base de datos mongo externa para development, strapi devuelve un error.

Encuentro que en la configuración para production hay una propiedad extra uri.

Cuando se usa esta propiedad uri en la configuración para development, ya es posible conectarse a una base de datos mongo externa, como mlab, por ejemplo.

Solución

  • $ strapi new myapp
    • Crear la aplicación indicando una base de datos mongo local
    • Esto aún no creará ninguna base de datos
  • Editar myapp/config/environments/development/database.json y agregar la propiedad uri:
  • $ cd myapp
  • $ strapi start
La configuración sería similar a:
{
  "defaultConnection": "default",
  "connections": {
    "default": {
      "connector": "strapi-hook-mongoose",
      "settings": {
        "client": "mongo",
        "uri": "mongodb://username:password@hostname.mlab.com:12345/dbname",
        "host": "hostname.mlab.com",
        "srv": false,
        "port": "12345",
        "database": "dbname",
        "username": "username",
        "password": "password"
      },
      "options": {
        "authenticationDatabase": "",
        "ssl": false
      }
    }
  }
}

2017/12/13

Test de internet con ping en NodeJS


En estos días he tenido intermitencias en el servicio de internet.

Mi forma de comprobarlo es entrar en una consola y hacer ping a un host, como google.com, y ver si está ok o no.

$ ping google.com -t


El -t permite que el ping se haga indefinidamente, hasta que se presione CTR + C.

Sin embargo, quería una forma de mostrar los cambios de estado, a qué hora ocurrían y cuánto duraban.

Programé esta solución usando nodejs:

GitHub Gist: Internet test with ping in NodeJS

const ping = require('ping');

let host = '8.8.8.8';

if (process.argv[2]) {
  host = process.argv[2];
} else {
  console.log("Syntax: \nnode ping-test-ifchanges-host host");
}

console.log("Testing host: " + host);

let isAlivePrev = false;
let nowPrev = new Date();

function doPing() {
  ping.sys.probe(host, isAlive => {
    if (isAlive !== isAlivePrev) {
      let now = new Date();
      let diff = (now.getTime() - nowPrev.getTime())/1000;
      let timestamp = now.toISOString() + ' after: ' + diff + ' s';
      console.log("\n" 
        + host + ': ' 
        + (isAlive ? ' OK' : ' KO') 
        + ' ' + timestamp);
      isAlivePrev = isAlive;
      nowPrev = now;
    } else {
      process.stdout.write('.');
    }
  });
}

setInterval(doPing, 1000);

Para correrlo en consola:

$ node ping-test-ifchanges-host google.com

Idea

setInterval() establece un llamado, cada 1000 ms, a doPing(), que hace un ping al host que se haya indicado y revisa si hay un cambio de estado.

Si hay un cambio de estado, anota el tiempo y muestra las diferencias respecto al tiempo anterior.

Si no hay cambio de estado, imprime simplemente un punto.

2017/12/04

CSS: Checkbox hack para controles personalizados

¿Cómo aplicar un estilo como respuesta a un click, usando sólamente CSS?

Se puede hacer con el checkbox hack.

Principio

  • Un label asociado a un input puede recibir el click por él
    • Puede haber varios labels para un mismo input
    • Ocultando el input (difícil de personalizar), queda el label para contener un control más fácil de personalizar
  • La pseudoclass :checked permite ubicar un checkbox seleccionado
  • El selector aaa + bbb permite seleccionar un bbb que esté (declarado) inmediatamente después de un aaa

Patrón 1

HTML:
<input id="checkbox-control" type="checkbox">
<label for="checkbox-control">Control</label>

CSS:
#checkbox-control:checked + label {...}

Patrón 2

HTML:
<label for="checkbox-control">Control</label>
<input id="checkbox-control" type="checkbox">
<div class="target">Target</div>

CSS:
#checkbox-control:checked + .target {...} 

Patrón 3

HTML:
<input id="checkbox-control" type="checkbox">
<label for="checkbox-control">Control</label>
<div class="target">Target</div>

CSS:
#checkbox-control:checked + label {...}
#checkbox-control:checked + label + .target {...}

Ideas de aplicación

  • Checkbox personalizado
    • Toggle
  • Tabs
  • Dropdown menu
  • Dot control para slider
  • Árbol desplegable
Ver unos ejemplos en A check studio, en CodePen

Referencias