Here's my five latest blog posts - or you can browse a complete archive of all my posts since 2008.

About That Meetup.com Announcement

Remember: everything on this site, including this post, is my personal opinion, and does not reflect any official position of either Skills Matter or of the London .NET User Group.

A screenshot of the meetup.com website announcing their plans to charge members a $2 fee to register for events

https://www.meetup.com/lp/paymentchanges, 15 October 2019

The online community platform Meetup.com (hereafter known simply as Meetup) has just announced that “beginning in October, members of selected groups will be charged a small fee to reserve their spot at events”. (archive.org link) From the phrasing of their announcement, it sounds like Meetup will be charging people a $2 fee to register to attend an event – even if the event is free – and that 100% of that revenue will go to Meetup and none of it is passed on to the event organisers.

I’ve organised a .NET meetup group in London since 2016. Since 2018, I’ve also been CTO at Skills Matter, a company based in London that hosts hundreds of free meetups and tech events every year. That’s given me some fairly unique insights into the relationship between the Meetup platform, the people who organise and attend free community events, and the logistics behind running a free event.

Meetup is an odd platform. It’s a lowest common denominator, that’s used by songwriting clubs, running groups, coffee mornings and book clubs, as well as the tech meetups that we all know and love. And over the last few years, they’ve made changes to that platform that’s made it harder to run a tech meetup on their platform. For example, they’ve deprecated their rich text editor in favour of a minimal plain-text interface that makes it much more difficult to include speaker biographies and photographs in an event description.

Many people also aren’t aware that group organisers have no access to our group members’ contact information. They provide tools that let us contact attendees by email, but there’s no way to download a list of members’ email addresses. And it costs. The London .NET User Group is part of the .NET Foundation, which means they pay our subscription costs, but even running free events on their platform costs $19.99 per group, per month.

As a technology platform, it’s not great. It has mediocre usability and a very limited feature set. We can’t share slides or videos. There’s no way to share feedback with our speakers. There’s no facility for attendees to share their dietary requirements. There’s no sort of statistical modelling or forecasting to give organisers some idea of how many people will actually show up – I know of people in the LDNUG group on Meetup who have RSVPed ‘yes’ to every single event since 2016 and have never actually showed up to one, but it will still quite happily list them as ‘attending’ every single time, so good luck figuring out how much beer and pizza you’re going to need on the night. Patricia Aas very neatly summarised it thus:

But we still run London .NET on Meetup, and here’s why. When I announce one of our events on Meetup, I know I’ll get 50-100 RSVPs within 48 hours. If it’s a well-known speaker, I’ll get more like 200. And around 20% of those RSVPs will be complete strangers – people who have never been to one of our events before, who aren’t on any of our Slack chats or following us on Twitter. The only way those people even know that our event is even happening is that they found it on Meetup – and Meetup is so dominant in this space that if your event’s not on Meetup, it may as well not exist.

The recent announcement here about charging attendees to register is interesting. Now, $2 is not a big deal for tech events – here in London that’s significantly less than a cup of coffee. And I wouldn’t be surprised if it’s part of some long-term strategy by Meetup to pivot to a subscription model by jacking the prices up now, and then offering a subscription model in a few months time that looks very reasonable by comparison (“Hey, check out Meetup Unlimited – only $5/month to register for as many events as you want!”). After all, Meetup is owned by WeWork, who are losing vast amounts of money right now and probably desperate for revenue; I suspect if you took a look at their business plan, free meetup attendees are listed under ‘stuff that doesn’t make enough money’. There’s a great write-up by Quincy Larson, the founder of freeCodeCamp.org, about this as well.

But the impact of that change, from free to $2, is far more psychological than financial – and that’s why it might be a game-changer. The announcement has already inspired people around the world to start working on their own version of Meetup – I’m on a Discord channel right now where the FreeCodeCamp folks are coordinating one such solution, and over 100 people have joined that channel in the time it’s taken to write this post. Only time will tell whether this is a flash in the pan or genuine critical mass, but their solution is called Chapter, it’s over at github.com/freeCodeCamp/chapter, and it’s definitely worth keeping an eye on.

Now, I love the way the tech community rallies like this around an opportunity – but we really don’t need a dozen different open-source codebases hosted on hundreds of isolated websites, each of them running a handful of local groups. And when you get into mobile apps, where you can’t just spin up a Docker container and import your data, the fragmentation problem is even more pronounced. The problem that Meetup solves is not a hard technical problem. It’s a social problem. If people can’t find your group, nobody’s going to come to your event.

That’s not a problem you can solve with database schemas and JavaScript frameworks. Sure, tech plays a role here – but if there’s one thing we can all learn from Meetup, it’s that mindshare and user adoption are way more important than features and design when it comes to growing user groups, events and communities. People will put up with poor usability and terrible design if it connects them to the right people – and if it doesn’t, there’s no amount of shiny technology and beautiful UX that’s going to make up for it.

I’ll be really interested to see what happens next.

"About That Meetup.com Announcement" was posted by Dylan Beattie on 15 October 2019 • permalink

Publishing Talks

I used to blog a lot more than I do now. There’s a couple of reasons for that, not least that a lot of the discussion and engagement that used to happen on blog post comments has now moved to Twitter and StackOverflow. But mainly, it’s because these days almost all of my ‘writing’ time goes into creating talks for conferences and user groups - and that takes a huge amount of time.

Most of my talks start life as an outline - a title and a very broad overview of what I want to talk about - and an Evernote file full of code snippets, web links, observations and notes and scribblings. The first stage of turning that into an actual talk is to sit down and write it. I find it much, much easier to develop, edit and restructure ideas when they’re still text, before I’ve got as far as any slides or visuals or anything - and that means ending up with a written version of pretty much the entire talk, or one possible version thereof.

This is not an article or a report. It’s written for a very different audience, and intended to create a very different kind of engagement. When you’re talking on a stage, you have a connection with the audience. If something doesn’t work, you can normally tell immediately and can explain, clarify, apologise if necessary - live presentation is a daunting medium, but it’s also a very forgiving one if you know how to work with it.

It’s also not a script. Every time I deliver a talk, it’s different - there will be phrasing and jokes and references in the written form that get skipped because of timing, or because they didn’t fit with the context of a particular event, or because I just plain forgot to mention them. It happens.

It might help to think of it as an essay, in the original sense of the word:

Essayer is the French verb meaning “to try” and an essai is an attempt. An essay is something you write to try to figure something out.

Figure out what? You don’t know yet. And so you can’t begin with a thesis, because you don’t have one, and may never have one. An essay doesn’t begin with a statement, but with a question. In a real essay, you don’t take a position and defend it. You notice a door that’s ajar, and you open it and walk in to see what’s inside.

​ - Paul Graham, The Age of the Essay, 2014

Now, I’ve written five new talks this year - six, if you include collaborations. I write the way I talk, and I talk at about 200 words per minute - so a 60-minute talk is roughly equivalent to writing a 12,000-word essay. And that essay then forms the backbone of the talk itself - the structure, the flow and the narrative; it’s what I use to create slides, work out where to use code samples, animation and video. But until now, I’ve never actually published it.

So I’m going to try an experiment. I’ve taken one of the talks I prepared this year - a talk called ‘The Cost of Code’ - and cleaned it up a bit. I’ve added most of the slides used in the live presentation, incorporated links to my source material, and put it all online.

It’s at https://dylanbeattie.net/articles/the-cost-of-code/ - check it out, and let me know what you think.

"Publishing Talks" was posted by Dylan Beattie on 06 October 2019 • permalink

Migrating from Blogger to GitHub Pages

So, you might have noticed I’ve done a bit of decorating… welcome to the 2019 incarnation of dylanbeattie.net. If you’re interested in how I migrated ten years’ worth of blog posts onto a Jekyll site hosted on GitHub Pages, read on. If you’re not, there’s funny videos over on /music that you might enjoy.

Still here? Cool! OK, so the very first version of dylanbeattie.net was a site I built in PHP back in 1999 or so, which I hosted on my own physical server – way back in the days when both of those things were still considered a pretty neat idea. About ten years I ago I started using Blogger, and before long I scrapped the old PHP site, pointed the main domain at my Blogger site, and just sort of got on with it.

Blogger’s been a pretty good platform, but these days I find I actually need a website to do a lot more than just host blog posts and the occasional ‘about me’ page, so a few months back I started looking around for alternatives. I’d considered setting up something like Umbraco, or a custom Wordpress site, but even those felt a bit like over-engineering for what I actually needed to do. My requirements basically boiled down to:

  • A really easy way to post articles – text and links with some simple formatting and the occasional image
  • The option to use rich HTML pages and custom layouts
  • Preserving the URIs of all my existing posts and pages – remember, cool URIs don’t change. Besides, I’ve got a decades’ worth of Google-fu invested in those pages. It’d suck if all those links and bookmarks stopped working.
  • Something that looked good, and a responsive layout that worked well across devices.

There’s also a couple of things I decided I definitely didn’t want:

  • Comments. It’s been years since I saw a decent discussion in the comments thread of a blog post. We have Twitter and Reddit for that now.
  • Bootstrap. I’m sure it’s lovely. I just don’t like it.

Back in January, I was chatting with Todd Gardner about how he created the PubConf website, and he suggested I take a look at GitHub Pages and a thing called Jekyll. I spent an evening playing around with it, and was basically hooked.

Jekyll and GitHub Pages

Note: the code for this site is available on GitHub at github.com/dylanbeattie/dylanbeattie.net

So here’s how it works. You write your site in HTML or Markdown, and create datasets in YAML. Jekyll compiles them into a static HTML site. It supports a templating language called Liquid, which lets you create templates, conditionals, navigation – you can actually do some pretty sophisticated stuff with it, but everything happens at build time. Which is actually very cool.

The really great part is that GitHub Pages has built-in support for Jekyll – so you build your site locally, using bundle exec jekyll serve to view it, then you just push the repo to GitHub and it’ll build and deploy it for you. It’s a beautifully simple workflow, but one that affords a surprising amount of flexibility once you get the hang of it.

Here’s some fun little things I learned along the way, and a couple of gotchas to watch out for if this inspires you to try something similar.

Design and layout

The design for my new site is the Arcana template by HTML5 UP, which is not only beautiful, responsive and really well put together, but is also released – like all HTML5 UP’s templates – under a Creative Commons Attribution 3.0 License:

“…which means you can use them for personal stuff, use them for commercial stuff, change them however you like … all for free, yo. In exchange, just give HTML5 UP credit for the design and tell your friends about it :)”.

Which is lovely. You see, I’m quite happy doing my own design work – and that’s the problem. I enjoy it. I get sidetracked. I spend hours – days – tweaking layouts and playing around with things, when I should be writing content and fixing bugs… and I end up with something that’s OK, but nothing like as good as some of the amazing templates and layouts that are available online, for free. So credit (and thanks!) to HTML5 UP for the design. I’ve made a couple of tweaks and added a few extra bits, but the layouts, grid, responsive design, navigation, typography – that’s all them. Oh, and it’s all built on SASS – which is also supported by GitHub Pages. Did I mention how much I love this platform?

Migrating old blog posts

This turned out to be a lot easier than I expected. There’s a Ruby gem designed to do exactly this – check out the Jekyll documentation and this blog post from Kris Rice which goes into a bit more detail about it.

Once I’d migrated all the posts from my old Blogger site, I wanted to make sure all the old page URLs would still work. I didn’t want to mess too much with Jekyll’s conventions about structuring posts, though – Jekyll uses a YYYY-MM-DD-title format for URLS compared to Blogger’s YYYY-MM-title format, and so I simultaneously wanted to adopt the Jekyll convention for new posts, to make things easier, but also to preserve the addresses of all my old posts so bookmarks and links still work.

Turns out the jekyll-migrate gem adds some lines to the top of each migrated HTML file – what Jekyll refers to as ‘front matter’ – that can help:

---
layout: post
title: How to *really* break the internet.
date: '2016-03-23T12:08:00.000Z'
author: Dylan Beattie
tags: 
modified_time: '2016-03-23T14:06:37.095Z'
blogger_id: tag:blogger.com,1999:blog-7295454224203070190.post-8996121207980120854
blogger_orig_url: http://www.dylanbeattie.net/2016/03/how-to-really-break-internet.html
---

There’s also a Jekyll plugin called redirect-from, which is part of the github-pages bundle (and, yes, it works a little like the infamous COMEFROM flow control statement beloved of sadistic esolang designers). So all I had to do was trawl through every file in the _posts folder, find that line with the blogger_orig_url in it, parse the path part out of the URL, and add a line underneath like this:

blogger_orig_url: http://www.dylanbeattie.net/2016/03/how-to-really-break-internet.html
redirect_from: "/2016/03/how-to-really-break-internet.html"

(Sorry, awk fans – I actually did this with a global search & replace in VS Code…)

That’s it – Jekyll now hosts all those pages at their new /2016/03/23/how-to-really-break-internet.html addresses, and requesting the original URL returns this:

<!DOCTYPE html>
<html lang="en-US">
<meta charset="utf-8">
<title>Redirecting&hellip;</title>
<link rel="canonical" href="/2016/03/23/how-to-really-break-internet.html">
<script>
  location="/2016/03/23/how-to-really-break-internet.html"
</script>
<meta http-equiv="refresh" content="0; url=/2016/03/23/how-to-really-break-internet.html">
<meta name="robots" content="noindex">
<h1>Redirecting&hellip;</h1>
<a href="/2016/03/23/how-to-really-break-internet.html">Click here...</a>
</html>

It’s not quite perfect – an HTTP 301 Moved Permanently would strictly speaking be a better way of handling this – but hey, perfect is the enemy of good enough. It works. Ship it.

Events schedule and flags

You see that little sidebar there, with all the events I’m speaking at and the flags in it of the countries I’m gonna be visiting? The flag images are from GoSquared, and available under an MIT license. To display them in the schedule, I’ve used a SASS list to generate CSS rules for each flag in the set:

/* _flags.scss: generate .flag-xx CSS classes for elements with flag backgrounds */

$countries: _abkhazia, _basque-country, _british-antarctic-territory, _commonwealth, 
  _england, _gosquared, _kosovo, _mars, _nagorno-karabakh, _nato, _northern-cyprus, 
  _olympics, _red-cross, _scotland, _somaliland, _south-ossetia, _united-nations, _wales, 
  AD, AE, AF, AG, AI, AL, AM, AN, AO, AQ, AR, AS, AT, AU, AW, AX, AZ, BA, BB, BD, BE, BF, 
  BG, BH, BI, BJ, BL, BM, BN, BO, BR, BS, BT, BW, BY, BZ, CA, CC, CD, CF, CG, CH, CI, CK, 
  CL, CM, CN, CO, CR, CU, CV, CW, CX, CY, CZ, DE, DJ, DK, DM, DO, DZ, EC, EE, EG, EH, ER, 
  ES, ET, EU, FI, FJ, FK, FM, FO, FR, GA, GB, GD, GE, GG, GH, GI, GL, GM, GN, GQ, GR, GS, 
  GT, GU, GW, GY, HK, HN, HR, HT, HU, IC, ID, IE, IL, IM, IN, IQ, IR, IS, IT, JE, JM, JO, 
  JP, KE, KG, KH, KI, KM, KN, KP, KR, KW, KY, KZ, LA, LB, LC, LI, LK, LR, LS, LT, LU, LV, 
  LY, MA, MC, MD, ME, MF, MG, MH, MK, ML, MM, MN, MO, MP, MQ, MR, MS, MT, MU, MV, MW, MX, 
  MY, MZ, NA, NC, NE, NF, NG, NI, NL, NO, NP, NR, NU, NZ, OM, PA, PE, PF, PG, PH, PK, PL, 
  PN, PR, PS, PT, PW, PY, QA, RO, RS, RU, RW, SA, SB, SC, SD, SE, SG, SH, SI, SK, SL, SM, 
  SN, SO, SR, SS, ST, SV, SY, SZ, TC, TD, TF, TG, TH, TJ, TK, TL, TM, TN, TO, TR, TT, TV, 
  TW, TZ, UA, UG, US, UY, UZ, VA, VC, VE, VG, VI, VN, VU, WF, WS, YE, YT, ZA, ZM, ZW;

@each $country in $countries {
  .flag-#{to-lower-case($country)} {
    background-image: url(images/flags/flat/64/#{$country}.png);
  }
}

The actual schedule is a YAML file, and Jekyll generates the markup with the correct CSS classes based on the country codes from schedule.yml. It’s easy to add new dates. The only thing it won’t do is automatically archive old ones- ‘cos hey, static content, remember? – but I reckon I can live with that for now.

(And yes, you can absolutely invite me to speak at your event by editing schedule.yml and sending me a PR. That would be really cool. :) )

Speaker bios

I’ve got a bunch of different speaker bios over at my about me page, and I really wanted a way to pick one and copy it to the clipboard as either HTML, Markdown or plain text – different events use different formats when you’re submitting to their CFP or filling out speaker details, and it’s a little thing that would make life easier.

The bios themselves are stored as multiline Markdown snippets in /_data/speaker_bios.yml. Instead of allowing Jekyll to just render Markdown > HTML automatically, I’ve got this little loop in the code for the about me page:

{% for bio in site.data.speaker_bios %}
<article>
  <hr />
  <h3>
    <span class="clipboard-links">
      <a href="#" data-src-id="{{bio.id}}-html">copy html</a>
      <a href="#" data-src-id="{{bio.id}}-markdown">copy markdown</a>
      <a href="#" data-src-id="{{bio.id}}-text">copy text</a>
    </span>
    {{ bio.word_count }} Word Bio ({{ bio.char_count }} characters)
  </h3>
  {{ bio.content | markdownify }}
	<input type="hidden" id="{{bio.id}}-markdown" 
	  value="{{ bio.content }}" />
	<input type="hidden" id="{{bio.id}}-html"
	  value="{{ bio.content | markdownify | escape_once }}" />
	<input type="hidden" id="{{bio.id}}-text"
	  value="{{ bio.content | markdownify | strip_html }}" />
</article>
{% endfor %}

so each snippet is rendered to the page as HTML (via the markdownify filter), and also captured in three hidden variables – one markdown, one HTML, one plain text. Finally, there’s some JavaScript attached to the ‘copy xxx’ links that’ll copy the hidden input value into an invisible textarea and copy it.

Syntax Highlighting

One of the great things about writing posts and pages in Markdown is that it’s so easy to embed code samples - just wrap them in three backticks either side, something known as a fenced code block. Jekyll has a code formatting plugin called Rouge, that’s included with the github-pages bundle, which allows you to specify a language for your code snippets and it’ll highlight them for you:

``` html
<p>This HTML snippet will get <a href="http://rouge.jneen.net/">highlighted</a></p>
```

To get this to work, I had to enable highlighting in _config.yml

markdown: kramdown
# enable rouge syntax highlighting
highlighter: rouge

I also had to add a stylesheet to the site with the various coloring rules - all Rouge does is wrap all the code keywords, etc. in <span> tags with CSS classes on them, so I found this syntax.css file on GitHub, dropped it into my site’s CSS, and it worked.

Gotchas

Pretty much everything I tried to do with Jekyll and GitHub Pages worked as documented, but I did hit two weird gotchas that caused a fair bit of head-scratching until I figured out what was going on…

Case sensitive filesystems

I’ve done most of the dev work for this site locally, on macOS 10.14, using bundle exec jekyll serve to preview and test things. And when I finally pushed the whole thing up to GitHub and switched on the GitHub Pages feature, everything worked – except the flag images in the schedule sidebar. And it took me a good couple of hours to figure out what was going on.

My original flags.scss file looked like this:

$countries: ad, ae, af, ag, ai, al...

@each $country in $countries {
  .flag-#{$country} {
    background-image: url(images/flags/flat/64/#{$country}.png);
  }
}

which generated a bunch of CSS rules that looked like this:

.flag-ad { background-image: url(images/flags/flat/64/ad.png); }
.flag-ae { background-image: url(images/flags/flat/64/ae.png); }

Now, if you look closely at the files in the GoSquared flagset I’m using, you’ll notice the filenames are:

AD.png
AE.png
AF.png

I’d dropped their entire flag set into my project, and pushed the whole thing to GitHub.

Now, I’m guessing that GitHub Pages is hosted on Linux. And Linux uses case-sensitive filesystems, whereas macOS – where I’d been testing everything – uses a ‘case preserving’ filesystem. In other words, if you ask macOS for ae.png, it’ll happily give you AE.png, but on Linux, ae.png and AE.png are different files.

So my CSS rule was telling my browser to ask GitHub Pages for ae.png, and GitHub’s Linux servers are going “nope. Not found.” – ‘cos the only file they’ve got is AE.png, which is COMPLETELY DIFFERENT. Obviously.

I could see two ways to fix this. One was to rename all the files in the GoSquared collection… but it turns out it’s surprising fiddly to rename a file from FILENAME to filename on macOS. The other, easier way is just to uppercase all the ISO country codes in the SCSS list, like this. I threw a to-lower-case($country) into the class name there because, well, I think uppercase CSS rules are vulgar.

$countries: AD, AE, AF, AG, AI, AL...

@each $country in $countries {
  .flag-#{to-lower-case($country)} {
    background-image: url(images/flags/flat/64/#{$country}.png);
  }
} 

DNS, HTTPS, Cloudflare and GitHub Pages

The last piece of the puzzle was to get the whole site using dylanbeattie.net (no www) as the canonical URL, and to get everything running over HTTPS. I host all my DNS with Cloudflare, because it’s free and works really well – and, like a lot of people, I’d relied on Cloudflare’s HTTP+DNS proxy service for a while to provide HTTPS for my old Blogger site (check out Troy Hunt’s Here’s Why Your Static Website Needs HTTPS for more on why this is a good idea.)

I wanted to use GitHub Pages to enforce HTTPS, but when I switched the Cloudflare DNS for dylanbeattie.net to point to GitHub’s servers, I couldn’t switch on the option to enforce HTTPS – instead, I got this error:

Enforce HTTPS — Unavailable for your site because your domain is not properly configured to support HTTPS

and when browsing my new site, I got a warning that:

This server could not prove that it is dylanbeattie.net; its security certificate is from www.github.com. This may be caused by a misconfiguration or an attacker intercepting your connection.

After about a day of head-scratching – change a DNS setting, wait six hours to see if anything happens, change something else, repeat – I contacted GitHub Support.

Turns out that Cloudflare’s DNS+HTTP Proxy feature actually interferes with the certificate issuing mechanism used to support HTTPS on GitHub Pages. GitHub asks for DNS servers so it can issue a certificate, but if you’ve enabled Cloudflare’s HTTP proxy feature (which is on by default, even on their free plan), Cloudflare responds to the DNS query with its own server addresses and so GitHub can’t see that your domain is pointing at GitHub Pages.

Logged into Cloudflare, switched the records for dylanbeattie.net over to DNS only, and boom – certificate was issued within the hour and everything was up and running.

"Migrating from Blogger to GitHub Pages" was posted by on 14 August 2019 • permalink

Saint-Petersburg, Russia - Tips for Tech Travellers

As I'm heading back to Saint-Petersburg for DotNext 2019, this seemed like a nice moment to repost something I wrote after my first visit to Russia back in 2017.

1. As a guest in Russia, it is vitally important to keep moving at all times. This is because if you stop moving for more than, say, fifteen seconds, your hosts will assume this is because you have run out of roast pork and sausages. It is impossible to sit down at a table in Saint Petersburg without somebody serving you a massive plate of meat. My hosts explained that the Russian phrase for 'no thankyou' is 'nyet, spasiba" but based on my experience I think this literally translates as "please bring me roast duck and cabbage now, and after that some more sausages".

2. Sausages in Russia occupy the culinary niche that is normally reserved for, say, some carrots in Western cuisine. You will find sausages chopped in a salad, boiled, fried, steamed, and served as accompaniments to all sorts of things.

3. Saint Petersburg is BIG. The average street here is wider than most London postcodes. If you have to walk three blocks, wear good shoes and take a bottle of water with you. Monuments and war memorials here are built to such a scale I can only assume they are intended to leave civilisations in neighbouring star systems in no doubt as to the nobility and sacrifice of the Russian military. We should give a special mention to the churches, which are not only huge, but we can conclude from the style of their decorated domes and minarets that the builders thought God had a bit of a thing for cupcakes.

4. Riding the Saint Petersburg metro will seem uncannily familiar to anybody who has read Jules Verne's "Journey to the Centre of the Earth". After buying your metro token from the ticket machine and passing through one of the metal detector arches - for which you are not required to empty your pockets or anything, meaning that they go off constantly and are consequently ignored by everybody including the police - you step onto an escalator approximately fourteen miles in length. The tunnels and station interchanges suggest that tunnelling machines in the former Soviet Union were available in two sizes - Extra Large and Stupidly Extra Large - and the interchanges are so big that the connected stations have different names. If, say, the Red Bull Air Race ever needed to be held indoors due to inclement weather, the pedestrian interchange tunnel at Spasskaya/Sadovaya would provide an ideal venue.

5. For typography enthusiasts, the Cyrillic alphabet is an absolute delight... except when it comes to handwriting. Cursive Cyrillic is a minefield of hilarity and ambiguity. Any doctors who feel they have exhausted the possibilities of the Latin alphabet when it comes to writing illegible prescriptions will find Cyrillic a rich seam of possibility.

6. The Russian people are lovely and friendly... once you get used to the fact that a Russian telling you a joke will initially sound like they're interrogating about some war crimes you may or not have committed. It helps to keep a Polish person with you, since they seem to know the correct point to start laughing, thus giving a handy cue to the slightly baffled English speakers participating in the conversation.

7. An English person trying to speak Russian is the funniest thing that has ever happened. The Russian equivalent of the Edinburgh Festival consists entirely of English people attempting to pronounce the names of Saint Petersburg metro stations whilst the audience drink vodka and roar with laughter.

8. Vodka must be served no warmer than -273.1499 degrees Celsius. To offer someone vodka that is merely refrigerated could cause a serious diplomatic incident.

9. Most consonants in Russian have a 'hard' and a 'soft' pronunciation, which, like tonal Cantonese or the tongue-clicks of the Khoisan language family, is completely impenetrable to foreigners. It is very important, however: based on my attempts to speak Russian to waiters, I have concluded that the elusive hard vs soft 'T' sound must be the difference between saying "no thank you, I have eaten so much food I think I need to to go the hospital" and "could I please have some more roast pork and boiled sausages"

10. There are a lot of Chinese tourists in Saint Petersburg. Local regulations prohibit them from travelling in groups of fewer than fifty. If you arrive to check in to your hotel moments after a Chinese tour party has arrived, you may wish to pass the time whilst you wait by reading the collected works of Dostoyevsky or walking to Vladivostok and back.

11. Every single car in Russia has a dashboard camera recording video footage of the journey, presumably so that when your cab gets cut up by another one and causes a six-car pile-up, the driver can pay the repair bills by sharing the crash footage on YouTube and hoping it goes viral. Most cab drivers keep their radio tuned to the local high-energy Europop station, so when they do inevitably have a massive crash, the resulting YouTube footage already has the appropriate soundtrack.

In short... it was AWESOME. The city is beautiful and vast and unlike anywhere I have ever been, the people could not have been more welcoming and friendly; arrival and departure was an absolute breeze thanks to the brand new, hyper-modern airport terminal building, and the metro is a great way to get around (and clearly signed in English throughout.) And if you don't fancy jumping through the administrative hoops of getting a Russian visa, you can visit SPB on a cruise ship from Tallinn or Helsinki and stay for up to 72 hours without having to get a visa, which is kinda cool.

Just don't stay up drinking vodka the night before your 5am departure. Trust me on this. :) "Saint-Petersburg, Russia - Tips for Tech Travellers" was posted by Dylan Beattie on 14 May 2019 • permalink

A release notes bookmarkdownlet for Pivotal Tracker

One of the best ways to keep the rest of your team up to speed with what your dev teams are doing is release notes - even if all you're doing is gently reassuring the rest of the organisation that yes, you are patching security vulnerabilities, fixing bugs and quietly making things better.

I love using Slack for this - set up a channel where you post a friendly summary of everything that's being released whenever you deploy to production. Now, here at Skills Matter we're not quite doing continuous deployment yet - we work off short-lived branches that merge to master several times a day, but then once master has passed regression testing on our staging environment, the actual deployment to production is a manual process - we open a master > production pull request in GitHub, merge it, and Heroku does the rest.

We track work in progress using Pivotal Tracker, and we use the various ticket state transitions as:

  • Start > a developer has created a branch and begun coding the features
  • Finish > the code is done; time for code review
  • Deliver > the code has been reviewed, merged to master and deployed to the staging environment
  • Accept > the code has been tested on staging; stakeholders know it's ready, and we're good to go live.

Now, this definitely isn't the best branch/merge strategy in the world, but it's the one we've inherited and the one we're using until we've made enough changes to the codebase to be able to deploy PRs directly to review environments.

So when we do a production release, one of the things I do is to check which features are included in that release - that'll form a note that's part of the master > production pull request, and we'll also share it with the company via Slack. And this is a bit tedious, so today I threw together a little JavaScript bookmarklet that'll automate it for you.

Select the stories you want in Pivotal Tracker, click the bookmarklet, and it'll copy them to your clipboard as Markdown-formatted bullet points with the story IDs linked to your Pivotal project.

The JS code is here - add a bookmark, paste this whole lot (including the javascript: into the URL field:


And here's what it looks like in action:






"A release notes bookmarkdownlet for Pivotal Tracker" was posted by Dylan Beattie on 22 March 2019 • permalink