Thursday, 31 December 2020

The year that was, 2020

Well, shit. I'm writing this on the last day of 2020 and thank goodness this year is over. There are plenty of reasons I am very pleased to see the back of this horrible year (COVID being the obvious one) but this isn't the place to write about that. This annual post is traditionally about reviewing my new years resolutions and reminding myself of all the creative things I've managed to do. It has, after all, not all been Division and ... err ... Division 2.

  • 18 posts on this blog (19 including this one) - sixth consecutive year of a post per month
  • regular posts reflecting on life in lockdown
  • did some writing (and GMing) for a MUD
  • continued running a weekly exercise class in the park in Bath
  • another year of the Year in Pictures site - this is the sixth year and we're up to 29 photographers
  • started a Rails project linking Humble Choice to Steam tags, re-learning a load of good developer craft skills
  • rebuilt my server from scratch
  • learned about Github Actions
  • built a pihole for my home
  • renovated the home network at my parents' house (and made them a pihole too)
  • upgraded all my live projects to use a modern version of Ruby and etc
  • 298 contributions to various projects on github (well up on last year)
  • learned the basics of wood turning (and made two bowls)
  • extensive instagramming
  • loads of photos on my flickr stream

Resolution count - 6/10. Nice.

Frankly, I'm astounded that this year of all years I've managed this much. I also achieved one of my stretch goals (of five but that's not the point). This is testimony to my own levels of awesome. Or, more accurately, this is testimony to a lot of effort to not just disappear into work during lockdown.

Speaking of work, I deliberately don't reflect much on work int this post but there is something worth remembering. This year I made some decisions and moved out of London and back to Bath properly. While it has been in the middle of a pandemic, so hardly the homecoming I anticipated, it still has been fantastic to stop the commute and live in one place again.

Next year... well. I've been writing this review post for seven years now, starting way back in 2014. In the last few years each year I've written some variant of "this year has been all about work - something to change next year". Then I've utterly failed to actually follow through. With lockdowns and COVID, work and life are blurring which makes stepping away all the more difficult so this year I'm going to have to work much harder at building a non-work life. However, I've been making some progress recently with picking up programming again and as long as coffee shops reopen before too long I hope to carry this on and build on it.

Nobody knows what 2021 is going to bring. Normally, I write about wanting to do things and learn things and so on. But the world isn't set up for that at the moment. I have my normal hopes, but more importantly next year is about the people. Life is exceptionally dark at the moment, so what can I do to bring a little light?

2021. Here we go.

Monday, 21 December 2020

A first look at Github Actions with Rails and Postgres

In my last post, I mentioned that while upgrading my Heroku tech stack I noticed Codeship was experiencing some kind of outage. This seemed to stop anything appearing in the "checks" part of a pull request (including any kind of error message, which was a long way from helpful) and I decided to investigate Github Actions for my CI/CD needs.

I've been thinking about using Github Actions for a little while, for two reasons. First, I wanted to run my linting in my CI pipeline and I know of a rather good tutorial for getting started doing this using Actions (thanks Dean!). Second, this should move my CI config to the project repository (keeping it together and putting it under version control) and remove a dependency on a third party SaaS product. I can't help feeling that the recent Codeship outage (which I only noticed because the check was missing in my PR, and could easily have missed this) vindicates this last point.

As a side note, Codeship now seems to be fully working again.

Anyway, the Rubocop implementation is actually pretty straightforward, but it took me forever to get the tests running because of a few tricks and gotchas which I thought I'd record for posterity.


Let's start with a timesaver. I read a lot of examples while setting this up, and some had extensive Bundler config in them. However, if you're using the ruby/setup-ruby@v1 action for setting up Ruby (code here) and you put in:

    bundler-cache: true

It will just handle everything bundle-related with no more configuration. Hurrah!

Migrating Capybara driver to Apparition

I have no idea if anyone else is still using Capybara Webkit to drive their Capybara tests but I was. It has recently become a pain to install because the underlying library (QtWebKit) has been deprecated. I found this out after quite a while of trying to get the QtWebKit libraries accessible in my Action. That didn't work.

It seems Thoughtbot, the authors, agree with me and have deprecated the thing and recommend a move to Selenium or Apparition. I chose the latter because of claims of backwards compatibility and it was very easy to switch when I finally realised that this was a more sensible way forward. The changes can be seen in this commit along with the inclusion of an Action setting up the Chrome driver in my test workflow.

Configuring the database to work in a containerised world

Good grief this took me forever.

In theory, this is really easy - configure a Postgres database as a service, when the tests run connect it up, and bam. In practice it is also really easy, requiring minimal config to get it working. However, it requires getting a load of options to line up and since it's all running on Github servers, the feedback loop is annoyingly slow so painstakingly iterating through a million tiny variations to get to that simple working config took an eternity.

In the end, there were only two things to note.

First, when configuring the Postgres service one HAS to specify a port (despite it being the default port).

Second, remember to update the test database config in database.yml to accept some environment variables (and also default to allowing the tests to run locally). It's really easy to do when you actually remember to do it...

It's highly like these are more down to my own incompetence than anything hidden or surprising.

And done

And lo, it works. While it took a while to figure all the details out, the results are actually really simple and easy to duplicate for other Rails projects.

The whole change for implementing Github Actions and implementing the other updates can be seen in this PR.

Saturday, 19 December 2020

Upgrading to the Heroku-20 buildpack and Bundler 2

I figured it's about time to start moving my various running applications and kit to Ubuntu 20, now there is a new LTS version and well before v18 totally dies. I know I'm late to this party, but I've been busy.

Today I updated an application hosted on Heroku and since it wasn't 100% smooth thought I'd capture my steps, both for myself in future and anyone else who finds it useful.

The tech

  • Ruby on Rails application
  • Ruby 2.5.1 (Ubuntu 18 default version)
  • Bundler 1.17.3
  • Heroku on buildpack 18
  • Codeship for automated testing and deployment

The process

On Heroku, go to the app page then its settings. On this page you can change the stack via the big red "upgrade" button. This requires a redeploy of the application.

Back at the app, I updated by ruby version (.ruby-version file for me), installed bundler and ran bundle update --bundler to upgrade from Bundler to Bundler2. This provoked some other minor config changes, all in this diff.

Then Codeship broke. As in, it was totally down. Sigh. When this came back, the build was not working, giving me a deadlock error when running bundle install. This gotcha took a while to fix (hence writing this post). In the end, all I had to do was add gem update --system to the build setup commands before gem install bundler.

And voila, we're in the modern world and everything works.