I'm on Open Source Security: Updating open source dependencies (1 mins read).

Announcing my appearance as a guest on the Open Source Security podcast, talking about Renovate and dependency updates more generally.
Back to /posts/.
I'm on Open Source Security: Updating open source dependencies (1 mins read).

Announcing my appearance as a guest on the Open Source Security podcast, talking about Renovate and dependency updates more generally.
Worries about Open Source in the age of LLMs (6 mins read).
Some concerns I have with moving towards "don't use Open Source, get an LLM to generate the code you want" and where it'll take us.
November 2025's Desert Island Discs (1 mins read).
Defining the 8 songs I'd take to a desert island (if I had the choice, of course).
Building a more secure npm ecosystem with Mend Renovate (5 mins read).

Discover how Mend Renovate 42 is strengthening npm ecosystem security with "minimum release ageβ enforcement and best-practice defaults.
Finding missing releaseTimestamps in Renovate (3 mins read).

How to query your Renovate debug logs (or renovate-graph exports) for missing release timestamps.
Adding type hints to Renovate config.js files (1 mins read).

How to add JSDoc type hints to a config.js Renovate global self-hosting configuration file.
Creating a gh CLI extension for creating GitHub Discussions via category forms (2 mins read).

Announcing gh-discussions, an extension for the GitHub CLI that allows creating GitHub Discussions via category forms.
Using jqp for interactive queries with jq (1 mins read).
How you can use jqp to improve your experience with writing queries with jq.
Determining the digest for a GitHub Action (2 mins read).

A couple of different ways to look up the digest for a GitHub Action to pin it, as per best practices.
Setting up govulncheck in GitHub Actions with GitHub Code Scanning alerts (2 mins read).

How to set up govulncheck to check for CVEs in your Go projects using GitHub Actions and have the results show up as a GitHub Code Scanning alert.
Gotcha: referencing symlinks with go:embed result in irregular file errors (2 mins read).

Why you may see irregular file errors in Go, if you're trying to go:embed a symbolic link.
Starless: How we accidentally vanished our most popular GitHub repos (11 mins read).

How a change targeting internal GitHub repositories backfired and inadvertently made Elastic's public-facing repositories private.
I'm joining Mend to work on Renovate full-time (7 mins read).

Announcing my move to new job, working on Renovate (CLI and Enterprise) full-time, and looking back at my time at Elastic.
Additional lessons learned running Renovate at scale (14 mins read).

Some of the things I've learned about monitoring the usage of Renovate 'at scale' of hundreds of repositories.
GopherCon UK 2025 (10 mins read).

A writeup of the GopherCon UK 2025 conference.
Clearing Language Server Protocol (LSP) diagnostics in Neovim (1 mins read).

How to clear all diagnostic messages from your current buffer, in Neovim.
Running Docker images from other architectures, on Linux (1 mins read).
How to run an ARM64 Docker container when running on AMD64, on Linux.
Creating beautiful visualisations of dependency data with Evidence (8 mins read).

How to use Dependency Management Data and Evidence to create beautiful visualisations for insights about your dependency data.
Accessing (accidentally) 'used' tickets in The Trainline's app (2 mins read).
How to access your etickets for The Trainline, when you've (accidentally) clicked 'mark as used'.
Syncing the WAL with SQLite (2 mins read).

How to take an SQLite database that is using the Write Ahead Log (WAL) and perform a full checkpoint, to remove any state in the WAL.
I'm on Changelog and Friends: #define: props to astronomer (1 mins read).

Announcing my appearance on Changelog and Friends for the #define gameshow.
I'm on Fallthrough: Versioning: We Did It To Ourselves (1 mins read).

Announcing my appearance as a guest co-host on Fallthrough, talking about versioning.
I'm on Fallthrough: Why You're Wrong About REST (1 mins read).

Announcing my appearance as a guest co-host on Fallthrough, talking about REST, Hypermedia, and more.
A few tips for optimising Renovate for multi-team monorepos (10 mins read).

Some tips for making Renovate work even better when working on a large multi-team monorepo, where each team has different requirements for their Renovate usage.
Checking out the branch from a fork in GitHub Actions, when using pull_request_target (3 mins read).

How to use gh pr checkout to fetch a forked PR's branch, when using pull_request_target.
Disabling zsh history for a given shell session (1 mins read).
How to temporarily disable zsh saving history of interactive shell commands.
Generating Go code from JSON Schema documents (25 mins read).

Looking at a couple of common libraries for generating Go structs from JSON Schema documents.
Creating cross-compiled Docker images from Go binaries (4 mins read).

How to create a (Docker) container image that is cross-compiled for different architectures, and includes a Go binary that is also cross-compiled.
Generating a Renovate Report from someone else's repo (1 mins read).

How to get a Renovate Report - with full metadata - from any arbitrary repository.
Accessing your Renovate Dependency Dashboard, without GitHub/GitLab Issues enabled (3 mins read).

Releasing a proof-of-concept to render Dependency Dashboards for repositories that don't have issues enabled, as long as you have a Renovate Report.
Checking the digest for a Docker image, using crane (2 mins read).
How to get a Docker image digest, using the crane CLI tool.
What's the difference between Renovate's depName and packageName? (3 mins read).

What the differences are, and where you may want to use one or the other.
My experience as a maintainer (8 mins read).
A guest post for opensource.org, about my experience as a maintainer, as part of 2025's Maintainer Month.
Taking more control over your Cobra CLI documentation (2 mins read).

Releasing a library to manage the generation of Cobra CLI documentation using text/templates.
Creating nested fenced code blocks with Hugo (1 mins read).

How to write a Markdown file with a fenced code block, which includes another code block inside it.
Setting up SSH key signing with Git (1 mins read).

How to sign your Git commits, using SSH keys.
Improving the experience of browsing Renovate debug logs (5 mins read).

Creating a Terminal User Interface (TUI) application to improve the debugging experience with Renovate's debug logs.
Looking back at oapi-codegen's last year (6 mins read).

A recap of oapi-codegen's last year, in light of it being Maintainer Month, and continuing to ask for sponsorship.
Overriding a Gradle project property which has . and _ characters, without modifying the buildscript (4 mins read).

How to use GRADLE_OPTS to safely override a Gradle property (with special characters in its name) without modifying the buildscript.
How to set up the 'Follow' button on LinkedIn (1 mins read).
How to allow others to follow you on LinkedIn.
Migrating secrets between two Vault instances (1 mins read).

How to copy secrets from one Vault instance to another, reducing the risk of the secrets being stored on disk for too long.
Using type assertions in Go with concrete types (2 mins read).

How to perform a type assertion on a type in Go that isn't an interface.
Getting Renovate to provide a changelog for digest updates to packages (on GitHub.com) (2 mins read).

How to use the new templated changelogUrl functionality to provide more actionable changelogs for digest updates to i.e. GitHub Actions and other digest-pinned dependencies (in this example, on GitHub.com).
Tricking oapi-codegen into working with OpenAPI 3.1 specs (7 mins read).

How to get oapi-codegen to interact with OpenAPI 3.1 specs, until it supports OpenAPI 3.1.
Gotcha: docker inspect can lie about the architecture of an image (3 mins read).
How incorrectly wiring up your Docker multi-platform builds may lead to docker inspect lying about the architecture of said image.
Rendering diffs for Go's testable examples (3 mins read).

A somewhat hacky solution for providing rich diffs for expected-vs-actual comparisons for testable examples in Go.
Authoring Markdown externally and pasting the 'pretty' output into Slack (on Linux) (3 mins read).
How to use xclip to copy the rendered representation of Markdown into a rich-text form into Slack.
Things I've learned about building + delivering software for other engineers while working in Engineering Productivity (17 mins read).
13 lessons I've learned about building software for (internal teams of) software engineers.
Properly patching packages: persistently producing patches for published projects, particularly practically prevented by patch-package policy (10 mins read).

How to use patch-package to modify NPM dependencies, for instance when you're distributing an executable and you want to patch something you rely upon, without relying upon postinstall scripts.
Automagically migrating golangci-lint configuration to v2 with Renovate (2 mins read).

How to get Renovate PRs that update both the version of golangci-lint to v2, and runs the golangci-lint migrate command for you.
I'm on Fallthrough: APIs: Design Imperfectly, Improve Relentlessly (2 mins read).

Announcing my appearance as a guest co-host on Fallthrough, talking about APIs and how to build them.
Logging into Hashicorp Vault via a GitHub token in the environment (1 mins read).
How to more easily log into Vault with a GitHub token, without having to enter it interactively.
Performing group_concat queries over distinct values, with a custom delimiter, with SQLite (2 mins read).

How to avoid SQLite's DISTINCT aggregates must have exactly one argument error when performing a group_concat(distinct ...) with a custom delimiter.
Updating apk add definitions in Dockerfiles (3 mins read).

How to use Renovate's Custom Regex manager to extract apk add definitions in a Dockerfile, to allow managing (un)pinned packages.
I'm on Fallthrough: An Exploration of APIs, Versioning, & HTTP (1 mins read).

Announcing my appearance as a guest on Fallthrough, talking about APIs, versioning, documentation, and more.
Creating single-purpose RSS feeds with Hugo (2 mins read).

How to create a new RSS feed in Hugo for a single page's updates.
Creating a test harness for validating Renovate Custom Datasource configuration (4 mins read).

How to set up a test harness to make it eaiser to modify scary looking JSONata transformations in your Renovate configuration.
Product requirements for a "fund your dependency tree" service (13 mins read).
Thinking about what functionality I would want as a funder, or a fundee, for a "fund your dependency tree" service.
I'm on Fallthrough: Patching Problems with Persnickety Proxies Purveyed by Paternalistic Princes (2 mins read).

Announcing my appearance as a guest host on Fallthrough, discussing the Go module proxy, pondering 'is Go dead?' and whether the Go team at Google have our best interests at heart.
Go 1.24's omitzero is another one of the best additions to the ecosystem in years (4 mins read).

Why I'm very excited about the JSON tag, omitzero, landing in Go 1.24.
Celebrating dependency-management-data's second birthday (7 mins read).

Reflecting on the last year of the project.
Go 1.24's go tool is one of the best additions to the ecosystem in years (8 mins read).

Why I'm very excited about go tool landing in Go 1.24.
Getting access to rich-text data from the clipboard (on Linux) (1 mins read).
How to use xclip to retrieve rich-text output from the clipboard.
Why is zsh no longer storing history? (1 mins read).
Spoiler: you may be missing both HISTSIZE and SAVEHIST variables.
Accessing private Go modules in a Docker container (4 mins read).

How to use a Personal Access Token or SSH to access a private Go module, from a Docker container.
Getting all comments from a given user on a GitHub Discussion (2 mins read).

How to use the GitHub GraphQL API to retrieve all comments from top-level or reply comments on a GitHub Discussion.
What level of access do I have on that GitHub repository? (2 mins read).

How to check, via the GitHub API, what access a given user has on a repository.