Ir al contenido

macOS

El mismo binario estático que en todas partes, compilado para darwin tanto en Apple silicon como en Intel. macOS no es una plataforma que solo se compile y se dé por buena: cada cambio ejecuta la suite unitaria entera y la suite de extremo a extremo en un runner de macOS, junto a Linux y Windows.

Ventana de terminal
curl -fsSL https://raw.githubusercontent.com/jmrplens/ghchronicle/main/install.sh | bash

Deduce la arquitectura, coge la release más nueva, comprueba el archivo contra la suma de verificación que esa release publicó, y deja el binario en /usr/local/bin si tiene permiso de escritura. Si no lo tiene, coge el primero de ~/.local/bin y ~/bin que exista y ya esté en tu PATH, y recurre a ~/.local/bin cuando no lo está ninguno. Una suma que no cuadra lo detiene sin instalar nada, y no hay opción para saltarse ese paso. Si cosign 2.4.2 o posterior ya está en la máquina, verifica además que el propio fichero de sumas viene del workflow de release, y una firma que cosign no confirma lo detiene, con lo que dijo cosign. Un cosign más antiguo no sabe leer el bundle de la firma, así que entonces, como sin cosign, dice que solo se verificó la suma. Termina ejecutando lo que ha instalado, así que la versión que ves es la del fichero recién escrito, y avisa cuando otro ghchronicle anterior en tu PATH sigue ganando el nombre.

Fijar una versión, o elegir dónde va:

Ventana de terminal
curl -fsSL https://raw.githubusercontent.com/jmrplens/ghchronicle/main/install.sh | VERSION=2.6.5 BIN_DIR=~/bin bash

El resto de esta página es esa misma instalación hecha a mano, que es lo que seguir cuando quieres saber exactamente qué ha aterrizado dónde, o cuando prefieres no ejecutar un script que no has escrito.

Los archivos de release dicen darwin, que es el nombre que la cadena de herramientas de Go da al sistema; macOS es el nombre que le da Apple. uname -m dice qué arquitectura es.

Lo que dice uname -mLa máquinaEl archivo que toca
arm64Apple silicondarwin_arm64
x86_64Inteldarwin_amd64
Ventana de terminal
VERSION=2.6.5
arch=$(uname -m); case "$arch" in x86_64) arch=amd64 ;; esac
base=https://github.com/jmrplens/ghchronicle/releases/download/v$VERSION
curl -fsSLO "$base/ghchronicle_${VERSION}_darwin_${arch}.tar.gz"

Junto a los archivos se publican dos ficheros: checksums.txt, que lleva el SHA-256 de cada archivo, y checksums.txt.sigstore.json, que es una firma sobre ese fichero.

  1. Coge el fichero de sumas y su firma.

    Ventana de terminal
    curl -fsSLO "$base/checksums.txt"
    curl -fsSLO "$base/checksums.txt.sigstore.json"
  2. Comprueba el archivo contra él. macOS trae shasum y no el sha256sum de una máquina Linux, así que se selecciona la línea de tu archivo y se le pasa por la tubería, que funciona con cualquier versión de shasum.

    Ventana de terminal
    grep "darwin_${arch}.tar.gz$" checksums.txt | shasum -a 256 -c -
    ghchronicle_2.6.5_darwin_arm64.tar.gz: OK
  3. Comprueba el propio fichero de sumas, si tienes cosign 2.4.2 o posterior. Uno más antiguo no sabe leer el bundle y falla diga lo que diga el fichero.

    Ventana de terminal
    cosign verify-blob \
    --certificate-identity-regexp 'https://github.com/jmrplens/ghchronicle/.github/workflows/release.yml@refs/tags/.*' \
    --certificate-oidc-issuer https://token.actions.githubusercontent.com \
    --bundle checksums.txt.sigstore.json \
    checksums.txt
    Verified OK

La firma es sin claves: la identidad que se verifica es el workflow que se ejecutó, anotado en un registro público de transparencia, y por eso las dos opciones --certificate no son opcionales. Sin ellas cosign confirmaría que alguien firmó el fichero, que no es la pregunta.

Después deja que escriba la configuración:

Ventana de terminal
ghchronicle -setup

Pide un token y dónde van los números, comprueba cada respuesta contra aquello que nombra, y escribe un config.yaml y, si lo quieres, un agente de launchd en ~/Library/LaunchAgents. El instalador de arriba lo ofrece como último paso.

El archivo lleva tres ficheros y ningún directorio.

  • Directorioghchronicle_VERSION_darwin_ARCH.tar.gz
    • ghchronicle el binario
    • LICENSE
    • README.md
Ventana de terminal
tar -xzf "ghchronicle_${VERSION}_darwin_${arch}.tar.gz" ghchronicle
sudo install -m 755 ghchronicle /usr/local/bin/
ghchronicle -version

/usr/local/bin está en el PATH por omisión de cualquier instalación de macOS, en las dos arquitecturas, porque /etc/paths lo lista el primero.

El binario necesita un fichero de configuración y un token, y el inicio rápido escribe los dos en seis pasos. Con eso hecho:

Ventana de terminal
ghchronicle -config config.yaml -list # qué se recogería
ghchronicle -config config.yaml -once # una pasada y termina

launchd es lo que macOS tiene en vez de systemd, y la primera decisión que te pide es agente o demonio.

Un LaunchAgentUn LaunchDaemon
Vive en~/Library/LaunchAgents//Library/LaunchDaemons/
Corre comotúroot, o el UserName que le des
Corre cuandohas iniciado sesiónla máquina está encendida, desde el arranque
Bueno paraun portátil que usasun Mac que se queda encendido

El agente es por donde empezar. No necesita sudo, y un colector que se para mientras el dueño del portátil está fuera de sesión no pierde nada que la siguiente pasada no recoja.

~/Library/LaunchAgents/io.jmrp.ghchronicle.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>io.jmrp.ghchronicle</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/ghchronicle</string>
<string>-config</string>
<string>/Users/tu/Library/Application Support/ghchronicle/config.yaml</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>GITHUB_TOKEN</key>
<string>github_pat_...</string>
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/tu/Library/Logs/ghchronicle.log</string>
<key>StandardErrorPath</key>
<string>/Users/tu/Library/Logs/ghchronicle.log</string>
</dict>
</plist>
  1. Protege el fichero antes de que lleve un token, y luego cárgalo.

    Ventana de terminal
    chmod 600 ~/Library/LaunchAgents/io.jmrp.ghchronicle.plist
    launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/io.jmrp.ghchronicle.plist
  2. Mira que está arriba, y lee lo que dice.

    Ventana de terminal
    launchctl print gui/$(id -u)/io.jmrp.ghchronicle
    tail -f ~/Library/Logs/ghchronicle.log
  3. Después de editar el fichero, descárgalo y vuelve a cargarlo. launchd lee la lista de propiedades una sola vez, al arrancarla.

    Ventana de terminal
    launchctl bootout gui/$(id -u)/io.jmrp.ghchronicle
    launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/io.jmrp.ghchronicle.plist

StartInterval es el cron de launchd, en segundos, y -once es el modo que le va. Sustituye KeepAlive por él y añade -once a ProgramArguments:

<key>StartInterval</key>
<integer>3600</integer>

Deja state_file en una ruta que sobreviva, en este modo sobre todo. Sin él cada ejecución recoge todas las familias, diga lo que diga su cadencia, y vuelve a recorrer la lista de estrellas, el historial entero de estrellas y las pull requests en coautoría; el fichero de caché que hay a su lado es lo que deja a una ejecución preguntar a GitHub solo por lo que cambió.

Go 1.27.1 o más nuevo es lo que declara el módulo. La compilación fija CGO_ENABLED=0, así que las herramientas de línea de órdenes de Xcode no hacen falta para ella.

Ventana de terminal
go install github.com/jmrplens/ghchronicle/v2/cmd/ghchronicle@latest

Cae en $(go env GOPATH)/bin, que es ~/go/bin salvo que lo hayas movido, y ese directorio tiene que estar en tu PATH. Un binario hecho así no tiene commit ni fecha de compilación de los que informar: esas dos las sella la compilación de release, y un módulo descargado por el proxy no lleva copia de trabajo de donde leerlas. -version nombra en su lugar lo que la compilación sí registra, la versión del módulo que descargó la orden go y la versión de Go que lo compiló:

ghchronicle 2.6.5 (module v2.6.5, built with <go version>)

El colector no busca el fichero de configuración en ningún sitio concreto: -config vale por omisión config.yaml relativo al directorio de trabajo, y detrás no hay ninguna ruta de búsqueda. macOS no tiene la costumbre de /etc/ghchronicle, así que estos son los sitios convencionales, no sitios que la herramienta conozca:

FicheroPara un agentePara un demonio
Configuración~/Library/Application Support/ghchronicle//usr/local/etc/ghchronicle/
Estado, registro, caché~/Library/Application Support/ghchronicle//usr/local/var/ghchronicle/
Log~/Library/Logs/ghchronicle.log/usr/local/var/log/

state_file tiene un valor por omisión propio, ghchronicle-state.json en el directorio de trabajo, con el registro de escrituras al lado como ghchronicle-state-written.bin y la caché como ghchronicle-state-cache.bin. El directorio de trabajo de un trabajo de launchd no es algo en lo que apoyarse. Ponlo. Desde la 2.6.1 un ajuste de ruta toma una ~ inicial como el directorio personal, así que la configuración de un agente puede decir state_file: ~/Library/Application Support/ghchronicle/state.json; una versión anterior lee la ~ como el nombre de un directorio, y quiere /Users/tu/... escrito entero.