Moving fast at GoCardless: why we invest in our workflow and processes
Last editedJun 2024 6 min read
At GoCardless, how we work is the secret sauce that allows us to deliver excellent customer experiences, from how we run customer support to how our design and marketing teams collaborate.
In this post, I’ll talk about how we changed the way we work over the last 9 months to build truly global software and introduce a localisation process which allows us to move quickly and deliver real value for customers.
We wanted to provide a great experience for our users, whatever language they speak — but it was imperative to do so in a way that didn’t slow us down as we continue to build out our product. When we get processes like this wrong, we not only make our team’s work harder than it needs to be, but we place a drag on what we care about most: delivering value for our users.
There’s a whole other post I could write about the intricacies of that process and how we’ve invested in sourcing skilled translators and ensuring we have perfect translations with quality assurance (QA) processes - but in this post, we’ll focus on the developer workflow.
The goal: building global software
When we launched the Dashboard back in 2016, we were much more firmly focused on the UK than we are today, so English-only was the natural way to go.
Now, we serve customers all over Europe and can collect payments from accounts in the UK, Sweden and across the Eurozone. We’re building a global bank-to-bank payments network which stretches far beyond the borders of the British Isles.
As such, we came to the conclusion in the middle of 2017 that we needed to move away from an English-first approach with only the most important flows translated (like our “payment pages” and merchant signup process), towards building global software, with the entire product available in our users’ native tongues.
The challenge: moving fast
Going multilingual means a dramatic upfront technical change, moving from hard-coded English copy across our product (from our emails to our API’s error messages) to “pointers” or “placeholders” which can be filled in with copy in the user’s language.
This first step towards building global software is known as internationalisation: moving from being in one language to supporting multiple languages. At this point, you don’t actually translate any copy into any new languages; you just put the infrastructure into place to support multiple languages.
If you’ve ever gone through this process of internationalisation, you’ll be aware of the traps which lay before us, from the challenges of pluralisation to making our UI look great whatever your language (for example in German, with its tendency towards very long words!).
We knew making this move from supporting one language to multiple would be a significant chunk of initial work.
But much more important, and often neglected, is the second step: localisation (l10n). Localisation is an ongoing process, as we translate copy written by our team in English into all of the languages we support.
It’s this ongoing long-term process that required the most thought and investment - we knew it’d stay with us and affect our product development work on a day-to-day basis, so we wanted to get it right.
Of course, it does also have an upfront element, when you first launch a new language, as the product as it stands is translated, but the ongoing element lasts into perpetuity: as we launch new features and tweak copy in English, we need to make sure our changes get reflected in our other supported languages.
From our limited forays into translating our product, centred around our “payment pages”, we knew that this process could be a real drag on how we work. We’d ended up with a localisation flow that involved emailing spreadsheets of strings between engineers and translators, with lots of copying-and-pasting, chasing and back-and-forth by email.
We weren’t satisfied with this. We pride ourselves on being able to move fast and deliver new features, bug fixes and improvements quickly, deploying many times a day. We invest in automation (for example automating how we build our API client libraries) so engineers can focus on adding value rather than going through repetitive processes.
Optimising our developer workflow means that our engineers can do what they do best and we can deliver the best products to our users.
We wanted to find a way of translating our product on an ongoing process which could be as automated and frictionless as possible.
The solution: imagining and building our ideal workflow
At GoCardless, the process of building software centres on GitHub:
As an engineer, I make a change to our code, and then push it up to GitHub
Our automated continuous integration process runs, making sure all of our automated tests pass
I create a pull request, and submit it for review by a colleague
Once my code has been reviewed, I can merge and deploy
With this workflow, our engineering team (now numbering more than 40) can be working on many things at once, with many pull requests open in parallel.
To kick off, we asked ourselves “what would the ideal localisation process look like?”. We came to the conclusion that it would:
Be set in motion from GitHub, where the developer already is
Slot in perfectly with a branch-based Git workflow, allowing us to work on multiple features at once and translate new and changed copy on a project-by-branch (that is, branch-by-branch) basis
Automatically work out what copy needed translating (i.e. what strings are new or different from the current state in our
master
branch) without the developer doing anythingRequire minimal intervention from the developer beyond saying “I’m ready” - no spreadsheets; no chasing; no back-and-forth
Automatically commit the translations back to my pull request as soon as they’re done
Having pictured our ideal process, we set out to understand how we could get there. After investigating a bunch of different translation management software (TMS) providers, we came to the conclusion that out-of-the-box, none of them came close enough to the workflow we were looking for.
Many of the TMS providers we found were a great fit in terms of their interface for translators, but not in terms of how they integrate into the development process.
All of the off-the-shelf options, even if they promised Git or GitHub integration, didn’t integrate into the “continuous delivery” philosophy which is at the centre of how we work - they required merging all of the work we’d done in a day or week into a “to be translated” branch and then sending it off for translation in a big bundler. We didn’t think that this was acceptable as a team that usually deploys 10+ times per day (and growing!).
From our research, we found that this wasn’t a solved problem. Searching the web for wise insights and clever solutions yielded nothing, and we chatted to larger tech teams and discovered that even they were often languishing with painful localisation processes that left them frustrated and slowed down innovation.
We came to the conclusion that it was worth building our own tooling to enable the workflow we wanted. Without a doubt, this was a costly choice up-front - building our own tools requires significant work in the here-and-now and maintenance in the long-term, but we were convinced that this investment was worthwhile given that we make many changes to our copy every day.
So we looked for a provider with a great API who would allow us to build our own tooling for getting copy to translate in and out of Git. After researching the options and trying a few out, we found our match: Smartling.
We ended up building a tool which we call the “i18n Relay”. Today, our workflow looks like this:
As an engineer, I make a change to our code, and then push it up to GitHub
Our automated continuous integration process runs, making sure all of our automated tests pass
I create a pull request, and submit it for review
The i18n Relay checks if any translations have been changed in the pull request. If they have, it posts a comment on GitHub with a link that the developer can click to submit their strings for translation.
I finish up my pull request — fixing any failing tests, getting it reviewed and making any last-minute tweaks — and then click the link to submit it for translation
The English copy is sent to Smartling, and a “job” is created to ask our localisation service provider (LSP), Pactera, to translate it
Within 48 hours, the copy is translated by our translators in Smartling’s interface, and as soon as everything is translated, it gets committed straight back to my pull request
Now, I can merge and deploy 🎉
The development process is inevitably slowed down as we have a new step of getting translations - but this delay is fairly short, and more importantly, the process is completely automated with no painful manual work for our engineers.
The philosophy: investing in our processes
In this post, we’ve seen just one example of how GoCardless invests in building the right company processes that help us to move fast and spend more time doing what we do best.
It would have been much “cheaper” in the short-term to just do everything manually and email spreadsheets back and forth - but that’s a process which doesn’t scale and in the long-term would have caused us to grind to a halt.
So we spent more time up-front finding the right workflow which optimises for developer happiness. When we couldn’t find an off-the-shelf solution, we imagined it and built it ourselves, starting with asking ourselves what the ideal process would be from a developer’s point of view.
With this workflow in place, we’ve been able to translate our whole product into French, German and Spanish (plus seven more languages for the parts of the product used by our users' customers), and we can now keep our translations in sync with no extra work for the developer as we add new features and tweak our English copy. What’s good for our developers is good for our customers.
We apply the philosophy of investing in our processes across GoCardless, and we’ve found that it really pays dividends.