Cronan the Deployer

The serendipity between a grumpy thought and a terrible pun is almost impossible to ignore. First off allow me to expand on my grumpy thought. Throughout my career I’ve been involved with a myriad of test, build, deploy, and release systems. The sort of thing that you would normally call build-monkey work, or release management, or DevOps, or whatever the hijacked term of art it is now. One way or another you want to get the code that was written by someone (please not something) into production in the most secure, safe, and dependable manner that you can....

Python CGI: a lost and poorly-documented art

I’ve been playing with webhooks in Codeberg (i.e. Forgejo). Forgejo have a very nice PHP example webhook handler. I know that I can write it as either a Python or a Go webapp but what if I don’t want to write another webapp and I just want something to process the JSON POST in the same way as the PHP script. Aside from the fact that the cgi module is deprecated since Python 3....

Bump semver tag in git

There are a number of scripts and git aliases that allow you to bump a semver tag in git, but none of them completely suit my needs. Consequently, I wrote my own bash script to do exactly what I need for my own admittedly-simple workflows. #!/usr/bin/env bash set -eo pipefail USAGE_TEXT="Bump and tag the current repository using semantic versioning (https://semver.org/). Usage: git-bump [options] [major|minor|patch] Default: patch Options: -n|--no-update Don't update repository before tagging....

bash: set -euxo pipefail

#!/usr/bin/env bash set -euxo pipefail Explanations from the Bash Reference Manual: -e Exit immediately if a pipeline, which may consist of a single simple command, a list, or a compound command returns a non-zero status. -u Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’, or array variables subscripted with ‘@’ or ‘*’, as an error when performing parameter expansion. An error message will be written to the standard error, and a non-interactive shell will exit....

Where is this IP coming from?

Sometimes you really want to know where an IP is coming from. Whether you are doing abuse or threat hunts, or just want to know who owns that IP blocked by fail2ban for spamming your SSH server. Each IP belongs to a specifc Autonomous System. An autonomous system (AS) is a very large network or group of networks with a single routing policy. Each AS is assigned a unique ASN, which is a number that identifies the AS....

Another password manager

I’ve been playing with password managers on and off for a long time. The first personal desktop app that I wrote was called JPasskeep and was written in Java Swing to explore Java’s cryptography and UI design and interaction patterns. It was a good experience and helped me get a gig as the UI engineer on a nifty Android project many years later. I’ve used JPasskeep on and off over the years, mostly on consulting gigs when I needed to store passwords on various development machines, and storing them as ....

I'm being stubborn

I’ve been writing a lot of Go code for the past few years and I have really come to appreciate the code generation patterns that Go developers use. In this case, the excellent Moq library to generate test doubles for unit tests. No third-party code is necessary to use these test doubles, which is an unusual joy nowadays with masses of transitive dependencies frequently required for anything interesting. One thing that has been bugging me for a while with moq is that in its documentation and generated code it calls these test doubles mocks when they are clearly stubs....

Detect dark mode in javascript

A reminder to myself, because I’ve forgotten this too many times and had to look it up again and again. if (window.matchMedia) { if (window.matchMedia('(prefers-color-scheme: dark)').matches) { const body = document.getElementsByTagName('body')[0]; body.classList.add('dark'); } } ...

Golang webapp skeleton

I’ve been writing webapps for a long time, and over that time I’ve written them in as may ways as possible. Currently my default is to create a simple server-side-rendered webapp in whatever language I use the most. Right now that is Go (or golang) so I’ve created a basic web application skeleton to make it easier to get something rolling without trying to figure out (or remember) how to link all the bits together....

Gotchas with static sites on S3 via CloudFront

There’s a ton of posts already on how to set up static sites hosted on S3 via CloudFront. This isn’t going to be one of them. What I want to discuss is some weirdness that I encountered with setting up this blog. For the purpose of this post we’re going to assume that you are going to create a hypothetical static site: https://example.com If you host a static site on hardware, or a VPS (be it an EC2 instance or a DigitalOcean Droplet) you’ll most likely do this with one of the various available web servers, like nginx or apache, and use a service like Let’s Encrypt to create the TLS certificate....