Writing

2026
When AI beats procrastination
Prompt Engineering for Humans
In the spotlight
Choose your losses
Never leave on a no
Update the AUR from GitHub Actions
Yes, if…
Delivery and Dopamine
Fix the inputs, not the outputs
When Asking is Easy (and Answering Isn't)
Visibility is Velocity
Bulk unsubscribe in Gmail
Building listentotaxman-cli with OpenCode + Claude Sonnet 4.5
2025
Electron Node module version
Toolsmiths melt snowflakes
Parse Codex jsonl with jq
Building gh-saved-issues using ChatGPT Codex
Display mirroring with Hammerspoon
Automated npm secret rotation in GitHub Actions
JSON semantic diff
Say three things
Run a container on a schedule with ECS
Pin your GitHub Actions
Output a JSON file with Jekyll
Running Scrumdog with Docker
Quality > Speed > Scope
Using AWS credential_process and 1Password
Slack channels are free
Excellent pull request reviews
Run go test -tags in VS Code
2024
Flatten nested foreach loops with Terraform
Bind a Hyper/Meh key with Keychron Launcher
Downloading webcomics with Dosage
Presentations on an ultrawide monitor
Kong Gateway quickstart
Designing OpenAPI schemas
Workspace layouts with Hammerspoon Grid
Could/Should/Will/Why
Create an AWS RDS database
Create an Azure AKS cluster
Does this live in the docs or on the knowledge base?
2023
Create an Amazon EKS cluster
How I work: Email
How I work: Sunsama
GitHub Actions notifications in Slack
Accessing secrets from forks safely with GitHub Actions
Set created_at with GitHub Actions when a PR is merged
kubectl autocomplete with ZSH and aliases
Spider-shaped DevRel
Show all issues for an epic in Confluence
Search for inactive users on Jira
Providing both default and named exports in JavaScript
Debug Jekyll with VSCode
Automatically set MetalLB IP addresses with kind
Testing Node.js SDKs with nock
Who hasn't gone yet?
Disagree horizontally, align vertically
Take a screenshot of a video using ffmpeg
GitHub scheduled reminders
Where should my content live? Docs or blog?
Carving the turkey
Obsidian - daily note + random review
Check permissions in a GitHub Actions workflow
The TAPE model for content
2022
Filter a Google Analytics report
Upgrade from Winston 2 to 3 using colors
Running gickup on a QNAP NAS
Transcribe audio locally on macOS
Secrets management in Kong is now GA!
Mock process.env using mocked-env
Using GITHUB_TOKEN as a default input value
Announcing general availability of Kong Gateway 3.0
API composition with StepZen and Kong
How I work: Pocket
Managing multiple environments with Konnect and Runtime Groups
Make an S3 bucket public
jamf stuck on “Locating hardware information (macOS 11.6.5)”
Remove Docker containers by tag
Update a single item in a list with vuex
Using openvpn-client with Docker
The GitHub wiki is an anti-pattern
2021
Log4j, Log4Shell and Kong
4 ways to leverage Kong's jq plugin
VSCode only showing one open tab
Convert a PDF to a stacked jpg
Test experimental versions with GitHub Actions
Dynamic matrix generation with GitHub Actions
Getting started with problem matchers
The ultimate guide to GitHub Actions authentication
Filter for dates before today with jq
Use a custom .zshrc with iTerm2
Deploying a Kong Gateway data plane with Pulumi
Minimal vim inspired .zshrc
Getting started with event hooks in Kong
Find AWS EC2 AMI owner ID
Get all keys in a list of objects with jq
Bundler ignoring BUNDLE_WITHOUT
BUNDLE_WITHOUT not working with development group
Kong-plement your ServiceHub with a dev portal
Upload an image with Puppeteer
Set a value in place with jq
Run node processes with systemd
Test OpenGraph image generation on Netlify locally
Migrating from Kong Gateway OSS to Konnect
Understanding .gitignore with git check-ignore
Building a Kong Gateway plugin with JavaScript
Using array.map with async/await
Dump context action
Show untracked files with git status
Auto-approve workflow action
array.filter with async/await
A better git blame with --ignore-rev
AWS federated login
Pin GitHub issues
Publishing a Ruby gem to the GitHub Package Registry
Group by fields with jq
Markdown Meta action
Generating OpenGraph images with Netlify on-demand builders
Return an image from Netlify Functions
Map object values .toLowerCase()
YAMLer Action
Concatenate strings in Nunjucks
GitHub Slug action
Use an Eleventy filter as an if statement
Add a Markdown filter to Eleventy
Create or Update PR action
Pause Laravel queue execution
Check if a row was created with Laravel updateOrCreate
Farewell, Nexmo/Vonage!
GitHub Push action
Add and Commit action
Git auto-commit action
Require Labels action
Merge Schedule action
Perform an action on team creation with Laravel Jetstream
Sum values with jq
Dedicated test databases with Laravel Sail
Ensure all nock mock interceptors are used
Faster GitHub Actions with Build and Tag Action
Ensure your GitHub Actions are pinned to a SHA
2020
Retag a Git tag
Download multiple videos with youtube-dl
CSS :target selector
Upgrade a Postgres DB
Gatsby category count
Show GitHub Actions
Find value of key recursively with JavaScript
Restore a file without adding to the index using Git
Show all files deleted since a Git commit
Fetch all pages with Octokit pagination
git shortlog reviewed-by
macOS power management with Hammerspoon
Adding a script tag using Gatsby JS
Follow GitHub Link headers with Bash
Action Router
Mock require with Jest
Semantic versioning for GitHub Actions
Improve your GitHub Actions security
2019
GraphQL is powerful, but the experience isn't designed
Trigger wp_insert_post_data handler on every post in WordPress
Create a GitHub Action using actions-toolkit
Testing GitHub Actions with act
Create a GitHub Action with Docker
Play an audio file into a voice call with PHP
2018
Building a Turkey Timer with Laravel and Facebook Messenger
Call whisper with selective audio controls
Multitrack call transcription with split recording
Michael, as your manager
Michael, as your colleague
Custom content types in Hugo
Creating a new Hugo theme
Receive an inbound voice call with PHP
Receiving SMS delivery receipts with PHP
Receiving an SMS with PHP
Dual channel call transcription with Nexmo
PSR-15 middleware, Zend Expressive and versioning
Middleware, Slim and versioning
Nexmo at Midwest PHP 2018
How to ruin a career in 10 easy minutes
Real-time messaging with Nexmo and Laravel
Mount Synology HDD under Linux
Why good leaders make you feel safe
Why developer relations programmes fail
Text-to-speech calls with Laravel and Nexmo
Speech-to-text with IBM Watson and PHP
Working with the Google Calendar API in Node.js
Google OAuth with Node.js
My favourite tweets
So, you want to be a wizard?
Sending and receiving SMS Laravel notifications with Nexmo
2017
A talk about naming things
Text-to-speech voice calls with PHP
Sending SMS messages with PHP
Michael is joining the Developer Relations team!
Farewell, Digi.me!
Jira Cloud + ScriptRunner
2FA logins with Laravel and Nexmo
SlimPHP and Symfony dependency injection
Bootstrap a new Laravel project with user authentication (in 5 minutes)
ChatOps with Nexmo Verify
Autoloading controllers with Composer in SlimPHP
Using controllers with SlimPHP
Using layouts with Twig and SlimPHP
Adding Twig to your SlimPHP project
Creating a new SlimPHP application
Creating an Azure Blob Storage with azure-cli
Customising the AuthController in Laravel Spark
TP-Link TL-WN823N on Arch Linux
2016
Test Kitchen, Docker and CentOS 7
Selecting a team via the URL in Laravel Spark
Using Azure Resource Manager with Terraform
Error while loading shared libraries: libbz2.so.1.0: cannot open shared object file on CentOS 7
Presenting 21 talks in 2016
Git and Node.js on Azure Functions
Using vagrant-hostmanager with centos/7
Connecting to a hidden network on Arch Linux
YubiKey on Arch
Farewell, DataSift!
Building with FPM
ffmpeg: Create a video from time-lapse photos
Extract keys using jq
YouCompleteMe on Arch Linux
Personal mission statement
Use OpenStack img in VirtualBox
I'm writing a book!
gpg: connecting dirmngr failed: IPC connect call failed
Creating a new user in MariaDB
Writing a conference talk
gpg: can't connect to the agent: IPC connect call failed
2015
Arch Linux: netctl and vpnc (Cisco VPN)
Todoist and me
Ansible without an inventory file
Viewing available Ansible facts
Setting the apt cache time using Ansible
Running gpg-agent on Ubuntu
Mounting msdos USB with permissions on OSX
Using GPG to securely send a message
Using INI config with python.logger
Fix: s3fs permission issue on remote folders
wiki
Rename a git branch
Build CentOS 5 generic RPM on CentOS 6
The class 'APCIterator' could not be found
Check if SSL certificate is SHA1 or SHA2
vim: Replace literal \n with new line
curl: (35) error:14094418:SSL routines:SSL3_READ_BYTES:tlsv1 alert unknown ca
curl: (58) unable to set private key file: 'server.key' type PEM
Vagrant: Require installed plugins
Use SCL packages without bash
Installing Ruby 1.9.3 on CentOS 6
Self-signed SSL client certificates
Special cron entries
Windows 8 temporary profile issue
Shared calendars on iOS (Google)
Git push
Jekyll: Failed to build gem native extension
git and diff-highlight
Introduction to vimrunner-python
2014
Convert .wav to .mp3 and set id3 tags
Golang: Get last character of a string
Dell XPS13/XPS15 white noise via audio
Extract substring of specific values with jq
Golang: How to go get private repos
Golang: Using Memcached
golang: Encode/Decode arbitrary JSON
golang: invalid operation: someVar == "" (mismatched types *string and string)
Working with Memcached via CLI
Using a custom startup script for xmonad
cowsay and Ansible
Writing an Ansible module using PHP
Setting up Ansible for hacking
Disabling comment formatting in Jira
Ansible: module is missing interpreter line
Installing Ansible from source on Ubuntu
Ansible: Installing Google Chrome on Ubuntu
ansible: ImportError: No module named ansible.playbook
alembic - TypeError: Boolean value of this clause is not defined
Python: Dynamically load all modules in a folder
PHP: return and the HEREDOC syntax
Using var_export to unit test existing code
alembic - Python migrations quick start
virtualenv and pip - a Python environment in 60 seconds
2013
A better git diff
Force flush headers using the HTTP module for Node.js
Start PolicyKit on Ubuntu
Explain, from your shell
Vim tips
Installing Vim 7.4 on Ubuntu
Useful git commands
A better git log
Administering multiple SSH shells simultaneously with cssh
Working with large files with sed
sed
Cache a specific URL with Varnish
.gitconfig
Out of my depth
extract
pv | mysql
Weekly breakdown - gxpr
Bang Bang
gxpr
z
cd -
CDPATH
GRC
Basic iptables rules
Building from source
Building for now
Uncaught exceptions
Blogging for yourself
Debugging Node.js memory leaks
Sending messages to certain clients with Socket.io
Installing ZSH 5.0 on CentOS 5.7
Installing Vim 7.3 on CentOS 5.7
Keyboard stops working on Ubuntu - slow-keys
Installing Node.js 0.8 on CentOS 5.7
CrashPlan: network blocked
Windows 7 installation: Xbox 360 Wireless Gaming Receiver for Windows
2012
Using the PHP SDK with Google BigQuery
ZSH config from scratch
Getting Solarized working on Ubuntu
Solarized with iTerm2
Behat + Selenium2 / WebDriver with MinkExtension
Behat + Selenium2 / WebDriver
How to: Make an Amazon AWS instance disk bigger
Never stop learning
The AWS Heisenbug
2011
Not enough random bytes available. [GPG Signing]
unetbootin - BOOTMGR is missing