Failed builds cost more than just time

I built a webhook which transfers £1 from my current account into a Monzo pot every time one of my builds fail. I’m going to explain what I did and why it involved more work than I first thought, this isn’t a tutorial but the code is on GitHub if you want to have a look.

I chose a stack that would challenge me to develop new and existing skills. It had been a while since I had written any Go, and it was a good opportunity to try out AWS Fargate. I started off with a simple web server to act as an endpoint to be called by the build system which would accept a POST request and print it to stdout. I bundled the app within a Docker container, opened up the AWS console and within 10 minutes it was deployed.

I could now add the callback to my build config so it would be called after every build, however I quickly ran into my first issue; CircleCI doesn’t allow environment variables to be used when defining a callback URL. This was a problem because I have no way of verifying the payload actually came from CircleCI.

I devised a solution which involved using the data in the payload to query the CircleCI API. It took some time trying to work out why my request to the API was failing, I now know that the Accept application/json header is required for their API to function.

Here is the CircleCI interface showing a failed build for a personal project. Most of my failed builds earning money for charity will be coming from my projects at Football Whispers.

With the endpoint operating and able to check whether a build has passed or failed, it was time to get to work on the fail jar.

Having looked at the Monzo API a few days before, it seemed like it would be nice and simple to transfer money into a pot (money you can’t spend until you transfer it back to your current account). However I’d assumed I could authenticate myself with a long-life API key. Instead I needed to setup an oAuth flow and then refresh the token regularly thereafter.

I setup a DynamoDB table to store my users’ access token and expiration, refreshing the token when it had expired. None of this was too difficult, but I certainly hadn’t expected to have to do this when I started.

I’d been sat on my sofa writing the code for most of the day, so once I’d finished I headed to Starbucks to write up the first draft of this post.

Success! I have money going into a pot every time a build fails. I hear you ask why this is actually costing me money since at the moment the money is mine, but in a separate part of my bank account. Well yeah you’re right. I’m going to run this for a few weeks / months and donate the money in the pot to charity.

This is not the most economical way of running an API like this. The smallest Fargate instance (0.25vCPU and 0.5gb memory) and provisioned DynamoDB table costs ~$13.43/month, and that’s before some additional costs such as the load balancer, ECR, and data transfer. This would be much cheaper running as a Lambda. But that’s not the point, this was just for fun.

Diagram showing the flow of data.

I wanted to work on something interesting, but which I could complete in a day despite not realising I would need to call the CircleCI API or setup an authentication flow with Monzo, this was comfortably a day’s work.

Any tech related charities you think I should donate the money to?

UPDATE: I stopped running this on the 4th July, as I’d actually only broken 7 builds in that time. I donated $50 to FIRST as suggested by Sam Weaver.