Cascading GitHub Action workflows for rebuilding static sites

A common pattern for building static sites on GitHub Pages (or similar) is to just trigger a new build every time there’s a change in the repository. This is very straightforward and well-tested, and works until you want to also trigger builds when something changes outside the repo. Then you run into some issues — but the solution, which took me some time to hunt down, turns out to be simple. The trick is specifying the right ref in your build workflow, and I explain why below.

Read more →

Recurse Center return statement, or What I did on my coding vacation

I’ve just wrapped a 12-week batch at Recurse Center, a self-directed coding retreat that provides an environment for people to become better programmers. I’m a huge fan of RC, and previously did a full batch in the summer of 2017 and a week-long minibatch at the start of 2019. It’s common for people finishing some time at Recurse Center to write up some notes afterwards, which are cutely called “return statements,” and that’s what I’m going to do here.

Read more →

Generating an infinite sea shanty in the browser

For a project I’m working on, I wanted to generate an endless looping soundtrack that felt like a sea shanty continuing indefinitely without a fixed melody. This proved to be a fun exercise for both musical and technical reasons, so I thought I’d write up some thoughts on how that came together.

Read more →

A new website for Malaika, tracking crossword publications

A few weeks ago, my friend Malaika Handa nerd-sniped me with an interesting request. She is a very prolific crossword constructor (think: multiple publications a week) and she keeps comprehensive records of those publications in a spreadsheet that is always up to date.1 She wanted a site to display that history in a clean and browsable way.

  1. You may know about her 7xwords project, which published crosswords for all the possible 7×7 grids over the course of a year, with 6 posts a week. I made two of them

Read more →

Using Google Sheets as a database for projects

As a software developer who enjoys working on hobby projects, especially with less technical collaborators, I have found myself using Google Sheets as a good-enough database in a lot of circumstances. I have lots of qualms about having the biggest of Big Tech in a load-bearing spot on these projects, but the practical benefits and the existence of a reasonable exit route have helped to quiet them.

Read more →

A Signal messenger API on your tailnet with Docker Compose

I’ve got a new configuration for sending Signal messages on the command line, and it’s powerful and flexible and finally gives me a nice ergonomic interface to use from other programs. Even cooler, it is accessible over Tailscale from any of my devices, which means I can securely reach it from multiple machines without going through the rigmarole of configuring and maintaining multiple copies of signal-cli.

Read more →

Real-time events with Bluesky and Jetstream for Helping Friendly Bot

This weekend I decided I needed real-time events from a particular Bluesky feed for a bot project. I was nervous that I’d have to consume events from the firehose, which seemed like it would require a lot of complexity and bandwidth, so I was relieved to learn about Jetstream, which solved my problem nicely. Here, I’ve got some notes about what I’m doing and how I’m doing it.

Read more →

10 years of pomological watercolors

A decade ago today I published a blog post calling for the US government to release its paintings of fruits. The Pomological Watercolor Collection, as I had recently come to know, is a beautiful and remarkable corpus of over 7,000 pictures of fruits and other biological specimens, made between the 1880s and 1940s. Through a handful of FOIA requests I’d learned that the images had been meticulously digitized and put online for purchase, but that less than 100 pictures had been sold that way — not nearly enough to justify the paywall.

Read more →