The Hacker News effect – wide but not deep

I posted a “Show HN” link to Hacker News on Saturday about my new product, Easy Data Transform. For some hours, nothing happened. No upvotes, no comments. One of the moderators emailed me suggesting I add my own comment. I did that and it started to get some upvotes and other comments. On Sunday I made it onto the front page of Hacker News and stayed there most of the day. The traffic to my new easydatatransform.com website jumped from negligible to around 300 page views per hour. Cool!

hacker-news-effect1

In total I got 4,400 unique page views and the discussion generated some 59 comments (including replies by me). Among the predictable ‘why isn’t a web app?’ and ‘why isn’t it on Linux’ questions, there was some useful feedback. But I was quite surprised how little most visitors engaged beyond that:

Visits to the home page: 3,289

Visits to the download page: 192

Installs of the free beta: 20

Signups to the mailing list: 0

I was also surprised that over 70% of the hits were from mobile devices and tablets. I guess that might partly account for the low download rate (Easy Data Transform is only available on Windows and Mac).

hackernews-os

But the session duration histogram tells it’s own story.

hackernew-analytics.png

0-10 seconds. Ouch.

 

 

 

Easy Data Transform video

I am continuing to work on my new product, Easy Data Transform. I have thrown together a 3 minute video to give an idea of what it is capable of.

Easy Data Transform video

You can download Easy Data Transform for Windows or Mac here. The beta is completely free, but time-limited (I do plan to start charging at some point). Please try it and let me know what you think.

I don’t really enjoy doing screencasts or voiceovers. If you can recommend someone who does slick screencasts and voiceovers (or who can polish my amateur attempts), please feel free to give them a plug in the comments.

Easy Data Transform

I have been furiously coding a new product. Easy Data Transform. It is a Windows and Mac tool for transforming table and list data from one form to another. Joining, splitting, reformatting, filtering, sorting etc.

easydatatransform

I have been thinking about this product idea for years. In fact I threw together a janky prototype back in 2008. It allows you to perform various operations on a pair of lists.

list-weaver

I used this prototype for jobs such as creating a list of emails of people who had bought Perfect Table Plan v5, but hadn’t upgraded to v6 yet. It worked. But it wasn’t very good. The biggest annoyance was that each operation obliterated everything that came before. Which made it very easy to lose track of where you had got to. And there was no repeatability. It was also limited to lists and it became clear that I really needed something that could also handle tabular data. I never released it.

But the idea has been running as a background process in my brain for 11 years since. And I think I have come up with a much better design in that time. Finally I had mature, stable versions of my Perfect Table Plan and Hyper Plan products out, so I decided to go for it. I am really pleased with how it has turned out so far.

If you aren’t embarrassed by v1.0 you didn’t release it early enough. And so I have cut lots of corners to get this first public version out. The documentation is only part written. I created the application icon myself  in 10 minutes. There is no licensing. The GUI is lacking polish. The website would make a designer cry. But the software seems fairly robust. My 13 year old son wasn’t able to crash it after 10 minutes of trying, despite financial incentives to do so.

I did some market research and spoke to some people who knew a bit about this market. But I deliberately didn’t look closely at any competing products, as I didn’t want to be mentally restricted by what others have done. For better or worse, I want to blaze my own trail. Copying other people’s stuff is a zero-sum game with no net benefit to society.

Most of the things that Easy Data Transform you can do, you can also do in Excel or SQL. My claim is that it is much quicker, easier and less error prone to do in Easy Data Transform. No programming or scripting required. I am hoping that people will be able to start using it within a couple of minutes of downloading it (I plan to do lots of usability testing). Will people pay for that? I hope so. I’m not aiming it at programmers. Perish the thought.

Naming is hard. I came up with some 70 names. Things like ‘Data Hero’, ‘Transform Flow’, ‘Transmogrify’ and ‘Data Rapture’. But the domains were taken, people I asked hated them or there was an existing service or product with that name. So I ended up with Easy Data Transform. It does what it says on the tin.

Why desktop? Surely no-one is writing new desktop apps in 2019? I believe a desktop solution has some real advantages in this market. The biggest ones are:

  • You don’t need to load your (potentially highly sensitive) data on to a third party server.
  • Not having to upload and download (potentially very large) data sets makes it much more responsive.

Easy Data Transform is currently free for anyone to use. You can get it from the super-minimalist easydatatransform.com website. The current 0.9.0 version expires on the 4th August 2019. You will then be able to get another free version. Once the product is mature enough, and if I am convinced there is enough demand, I will release a paid version. The free beta will probably last several months. Please try it and let me know how you get on. I am particularly interested to get feedback from anyone using it for real day-to-day tasks.

Of course the real challenge is always marketing. How to get noticed amongst many competing products. As well as helping to improve the product I am hoping that this extended beta will also help me to get some traction and better understand the market. For example, what price to charge and what trial model to use. Watch this space.

Bloviate

I wondered what it would look like if you took a body of text and then used it to generate new text, using Markov chains of different lengths. So I knocked up  quick program to try it.  ‘Bloviate’.

bloviate

Bloviate analyses your source text to find every sequence of N characters and then works out the frequency of characters that come next.

For example, if you set N=3 and your source text contains the following character sequences staring with ‘the’:

‘the ‘, ‘then’, ‘they’, ‘the ‘

Then ‘the’ should be followed 50% of the time by a space, 25% of the time by an ‘n’ and 25% of the time by a ‘y’.

Bloviate then creates output text, starting with the first N characters of the source text and filling in the rest randomly using the same sequence frequencies as the source text.

Note that a character is a character to Bloviate. It treats upper and lower case as different characters, makes no attempt to differentiate between letters, punctuation and white space and does not attempt to clean up the source text. Which also means it works on any language.

Bloviate also tells you the average number of different characters following each unique sequence of N, which I will call F here. As F approaches 1.0 the output text becomes closer and closer to the input text.

Using ‘Goldilocks and the 3 bears’ as input:

If N=1 (F=7.05) the output is garbage. Albeit garbage with the same character pair frequency as the original.

On cre She sl s ramy raked cheais Bus ore than s sherd up m. ged. bend staireomest p!”Sof ckstirigrorr a ry ps.

” f waine tind s aso Sowa t antthee aime bupis stht stooomed pie k is beche p!

At N=3 (F=1.44) it looks close to English, but jibberish:

Once up and been sight,” she this timed. Pretty so soon, she second soft. She screame up and she screame hot!” cried the Mama bed the Papa been sleeping in the Papa bear

“Someone’s bear growl.

At N=5 (F=1.14) it starts to look like proper English, but semantically weird:

Once upon a time, so she went for a walked right,” she lay down into the kitchen, Goldilocks sat in the porridge from the three chair,” growled, “Someone’s been sitting my porridge and she tasted the door, and ran down the bedroom. Goldilocks woke up and she second bowl.

And it comes out with occasional gems such as:

“Someone’s been sitting my porridge,” said the bedroom.

At N=10 (F=1.03) it starts to become reasonably coherent:

Once upon a time, there was a little tired. So, she walked into the forest. Pretty soon, she came upon a house. She knocked and, when no one answered, she walked right in.

At the table in the kitchen, there were three bowls of porridge.

At N=15 (F=1.01) it starts to get pretty close to the original text, but doesn’t follow quite the same order:

Once upon a time, there was a little girl named Goldilocks. She went for a walk in the forest. Pretty soon, she came upon a house. She knocked and, when no one answered, she walked right in.

At the table in the kitchen, there were three bowls of porridge. Goldilocks was very tired by this time, so she went upstairs to the bedroom. She lay down in the first bed, but it was too hard. Then she lay down in the third bed and it was just right. Goldilocks fell asleep.

At N=12 (F=1.07) the whole 680k characters of ‘Pride and prejudice’ produces:

It is a truth universally contradict it. Besides, there was a motive within her of goodwill which could not help saying:

“Oh, that my dear mother had more command over herself! She can have her own way.”

As she spoke she observed him looking at her earnest desire for their folly or their vice. He was fond of them.”

Obviously the source text is important. The Bohemian Rhapsody lyrics make nearly as much (or as little sense) at N=5 (F=1.08) as the original:

Is this to me, for me, to me

Mama, just a poor boy from this to me

Any way the truth

Mama, life? Is this time tomorrow

Carry on as if nothing all behind and face the truth

Mama, ooh, didn’t mean to me, baby!

Just gotta leave me and lightning, very fright out, just killed a man

Put a gun against his head

Pulled my time to die?

At N=12 (F=1.05) 160k characters of Trump election speeches produces:

Hillary brought death and disaster to Iraq, Syria and Libya, she empowered Iran, and she unleashed ISIS. Now she wants to raise your taxes very substantially. Highest taxed nation in the world is a tenant of mine in Manhattan, so many great people. These are people that have been stolen, stolen by either very stupid politicians ask me the question, how are you going to get rid of all the emails?” “Yes, ma’am, they’re gonna stay in this country blind. My contract with the American voter begins with a plan to end government that will not protect its people is a government corruption at the State Department of Justice is trying as hard as they can to protect religious liberty;

Supply your own joke.

I knocked together Bloviate in C++/Qt in a couple of hours, so it is far from commercial quality. But it is fairly robust, runs on Windows and Mac and can rewrite the whole of ‘Pride and prejudice’ in a few seconds. The core of Bloviate is just a map of the frequency of characters mapped to the character sequence they follow:

QMap< QString, QMap< QChar, int > >

You can get the Windows binaries here (~8MB, should work from Windows 7 onwards).

You can get the Mac binaries here (~11MB, should work from macOS 10.12 onwards).

Note that the Bloviate executable is tiny compared to the Qt library files. I could have tried to reduce the size of the downloads, but I didn’t.

To use Bloviate just:

  1. paste your source text in the left pane
  2. set the sequence length
  3. press the ‘Go >’ button

I included some source text files in the downloads.

You can get the source for Bloviate here (~1MB).

It should build on Qt 4 or 5 and is licensed as creative commons. If you modify it, just give me an attribution and send me a link to anything interesting you come up with.

How to notarize your software on macOS

** Please note: WordPress keeps mangling my code examples by changing double dash to single dash. I tried to fix it. But it changed them all back again! If anyone knows how to get around this, please put something in the comments. **

Apple now wants you to ‘notarize’ your software. This is a process where you upload your software to Apple’s server so it can be scanned and certified malware free. This will probably become compulsory at some point, even (especially?) if your software isn’t in the Apple app store. Apple says:

Give users even more confidence in your software by submitting it to Apple to be notarized. The service automatically scans your Developer ID-signed software and performs security checks. When it’s ready to export for distribution, a ticket is attached to your software to let Gatekeeper know it’s been notarized.

When users on macOS Mojave first open a notarized app, installer package, or disk image, they’ll see a more streamlined Gatekeeper dialog and have confidence that it is not known malware.

Note that in an upcoming release of macOS, Gatekeeper will require Developer ID signed software to be notarized by Apple.

Documentation on notarization is a bit thin on the ground, especially if you want to notarize software that wasn’t built using XCode (I build my software using QtCreator). So I am writing up my experiences here.

First you need to ensure you have macOS 10.14 and XCode 10 installed (with command line tools) and you need a current Apple developer account.

Codesign your app with ‘hardened runtime’ using –options runtime :

codesign –deep –force –verify –verbose –sign “Developer ID Application:<developer id>” –options runtime <app file>

E.g.:

codesign –deep –force –verify –verbose –sign “Developer ID Application: Acme Ltd” –options runtime myApp.app

A ‘hardened runtime’ limits the data and resourced an application can access. I’m not sure what the exact ramification of this are. But it doesn’t seem to have restrict my software from doing anything it could do previously.

You can check the signing with:

codesign –verify –verbose=4 <app file>

E.g.:

codesign –verify –verbose=4 myApp.app

Now package your app into a .dmg (e.g. using DropDMG). Then upload the .dmg to Apple’s servers:

xcrun altool -t osx -f <dmg file> –primary-bundle-id <bundle id> –notarize-app –username <username>

E.g.:

xcrun altool -t osx -f myApp.dmg –primary-bundle-id com.acme.myapp –notarize-app –username me@acme.com

You will be prompted for your Apple developer password (or you can include it on the command line).

You now have to wait a few minutes. If the upload is successful “No errors uploading ” will be shown and a unique ID will be returned. You then have to use this to request your upload be scanned:

xcrun altool –notarization-info <notarize ID> -u <username>

E.g.:

xcrun altool –notarization-info xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx -u me@acme.com

You will be prompted for your Apple developer password (or you can include it on the command line).

Hopefully you will see “Status Message: Package Approved”. If the notarization fails, you should be sent a link to an online log file describing the issue. If the notarization completes successfully you need to ‘staple’ the results to your .dmg:

xcrun stapler staple -v <dmg file>

E.g.:

xcrun stapler staple -v myApp.dmg

The stapler outputs a log including some odd phrases. Mine included: “Humanity must endure”, “Let’s see how that works out. “, “Adding 1 blobs to superblob. What about Blob?” and “Enjoy”. Weird. Hopefully it will end with “The staple and validate action worked!”.

Finally you can unpack your .dmg into a .app and verify it with:

spctl -a -v <app file>

E.g.

spctl -a -v /Applications/myApp.app

On macOS 10.14 (but not earlier OSs) it should say “source=Notarized Developer ID”. Your software should now run on 10.14 without a warning dialog. Congratulations!

It all seems rather clumsy. As you have to wait asynchronously for the unique ID to be returned from step 1 before you can complete step 2, it is not easy to fully automate in a script. This is a major pain the arse. If anyone works out a way to automate it the whole process, please let me know.

Here are some links to the various posts that I gleaned this information from:

https://cycling74.com/forums/apple-notarizing-for-mojave-10-14-and-beyond
https://www.mbsplugins.de/archive/2018-11-02/Notarize_apps_for_MacOS
https://forum.xojo.com/50655-how-to-codesign-and-notarise-your-app-for-macos-10-14-and-highe
https://forum.xojo.com/49408-10-14-hardened-runtime-and-app-notarization/11
https://stackoverflow.com/questions/53112078/how-to-upload-dmg-file-for-notarization-in-xcode
https://lapcatsoftware.com/articles/debugging-mojave.html

Qt is broken on macOS right now

Let me say up front that I am a big fan of the Qt framework. I have been working with it continuously since the late 90s. Both of my commercial products (PerfectTablePlan and Hyper Plan) are written on top of Qt. But Qt is quite broken on macOS right now. In fact I struggled to find a version of Qt 5 that supported recent versions of macOS and didn’t have a showstopper bug. I must have wasted a couple of weeks grappling with these issues. I am putting my notes here in the hope that they help someone else.

Here are the 4 bugs in macOS version of Qt that have causing me the most headaches:

Qt Version
bug v5.9.6 v5.10.1 v5.11.0 v5.11.1 v5.11.2
QFontDialog broken (link) ok ok ok ss ss
QStaticText::size() returns wrong value for rich text
with line breaks
ss ss ok ok ok
widgets such as QTableWidget do not repaint correctly (link) ok cwa cwa cwa cwa
default QComboBox size is incorrect (link)
ok ok cwa ok ok

Where:

ok = bug not present.

cwa = bug present, but can workaround.

ss= bug present, making release unusable for me (showstopper).

Consequently Qt 5.11.0 is the only usable release on macOS for me and I have to kludge my way around two quite nasty bugs. While the QStaticText issue is fairly obscure (but important for me), how in the hell did QFontDialog get completely broken without anyone noticing? And then not get fixed for two whole releases?! I also know other developers who are having to stick with earlier versions of Qt due to the bugginess of the recent versions of Qt on macOS. This isn’t good enough.

Thankfully the recent versions of Qt are much more solid on Windows.

** Feb-2019 Update: Qt 5.12.0 seems to be a big improvement. **

** Mar-2019 Update: I had to revert PerfectTablePlan to Qt 5.11.0 because versions built with 5.12.0 and 5.12.1 kept crashing deep in Qt. **

** Sep-2019 Update: I had to revert PerfectTablePlan to Qt 5.11.0  again because versions built with 5.12.4 kept crashing deep in Qt. **

** Oct-2019 Update: Qt 5.12.5 fixes all the bugs above and doesn’t seem to introduce any major new bugs that I care about. **

30 tips for creating great software releases

If a film director is only as good as their last film, then I guess a software developer is only as good as their last software release. In more than 30 years of writing software professionally I have shipped my fair share of releases. For the last 13 years I have been shipping software as a solo developer. Here are a few things I have learned along the way. Some of them are specific to downloadable software, but some of them apply equally to SaaS products.

Use a version control system

I occasionally hear about software developers who don’t use a version control system. Instead they usually create some sort of janky system using dated copies of source folders or zip files. This send shivers down my spine. Don’t be that guy. A version control system should be an essential part of every professional software developer’s tool kit. It matters less which version control system you use. All the cool kids now use distributed version control systems, such as git. But I find that Subversion is fine for my requirements.

Tag each release in version control

This makes it easy to go back and compare any two releases. A bug appeared in the printing between v1.1.1 and v1.1.2? Go back and diff the source files related to printing and review all the changes.

Store your release binaries in version control

I store every binary I ship to customers in my version control system. Many people will tell you that you should only store the source in version control. Then you can use this to regenerate the binaries if you need to. This was sound advice back in the day when harddisks were small, networks were slow, version control systems were clunky (SourceSafe!) and developer environments didn’t change very frequently. But I don’t think it is valid advice now. Harddisks are as cheap as chips, networks are much faster and online updates mean your SDK, compiler or some other element of your toolchain is likely to be updated between your releases, making it impossible for you to recreate an identical release binary later on.

‘Test what you ship, ship what you test’

In an analog system (such as a bridge) a tiny change in the system will usually only cause a small change in the behaviour. In a discrete system (such as software) a change to a single bit can make the difference between a solid release and a showstopper bug. The Mariner I rocket was destroyed by a single missing hyphen in the code. So test the binaries that you plan to ship to the customer. And if you change a single bit in the release, re-test it. You probably don’t need to run all the tests again. But you certainly can’t assume that a small change won’t cause a big problem.

This issue often manifests itself when the developers test the debug version of their executable and then ship the release version. They then find that the two have  different behaviour, e.g. due to a compiler optimization, different memory layout or code inside an ASSERT.

Make each executable individually identifiable

As a corollary of the above, you need to be able to uniquely identify each executable. I do this by having a timestamp visible in the ‘About’ box (you can use __DATE__ and __TIME__ macros in C++ for this) and ensure that I rebuild this source file for every release.

Diff your release with the previous one

Do a quick diff of your new release files versus the previous ones. Have any of the files changed unexpectedly? Are any files missing?

Be more cautious as you get nearer the release

Try not to make major changes to your code or toolchain near a release. It is too risky and it means lots of extra testing. Sometimes it is better to ship a release with a minor bug than fix it near the release and risk causing a much worse problem that might not get detected in testing.

Test your release on a clean machine

Most of us have probably sent out a release that didn’t work on a customer’s machine due to a missing dynamic library. Oops. Make sure you test your release on a non-development machine. VMs are useful for this. Don’t expect customers to be very impressed when you tell them ‘It works on my machine‘.

Test on a representative range of platforms

At least run a smoke test on the oldest and most recent version of each operating system you support.

Automate the testing where you can

Use unit tests and test harnesses to automate testing where practical. For example I can build a command line version of the seating optimization engine for my table plan software and run it on hundreds of sample seating plans overnight, to test changes haven’t broken anything.

If you set up a continuous integration server you can build a release and test it daily or even every commit. You can then quickly spot issues as soon as they appear. This makes bug fixing a lot easier than trying to work out what went wrong weeks down the line.

But still do manual testing

Automated test won’t pick up everything, especially with graphical user interface issues. So you still need to do manual testing. I find it is very useful to see real-time path coverage data during testing, for which I use Coverage Validator.

Use third parties

You can’t properly test your own software or proof read your own documentation any more than you can tickle yourself. So try to get other people involved. I have found that it is sometimes useful to pay testing companies to do additional testing. But I always do this in addition to (not instead of) my own testing.

Your documentation is an important part of the release. So make sure you get it proof read by someone different to the person that wrote it.

Use your customers

Even two computers with the same hardware specifications and operating system can be set up with an almost infinite range of user options (e.g. screen resolutions, mouse and language settings) and third party software (e.g. anti-virus). Getting customers involved in beta testing means you can cover a much wider range of setups.

When I am putting out a major new release I invite customers to join a beta mailing list and email them each time there is a new version they can test. In the past I have offered free upgrades to the customers who found the most bugs.

Don’t rely only on testing

I believe in a defence in depth approach to QA. Testing is just one element.

Automate the release process as much as you can

Typically a release process involves quite a few steps: building the executable, copying files, building the installer, adding a digital signature etc. Write a script to automate as much of this as possible. This saves time and reduces the likelihood of errors.

Use a checklist for everything else

There are typically lots of tasks that can’t be automated, such as writing release notes, updating the online FAQ, writing a newsletter etc. Create a comprehensive checklist that covers all these tasks and go through it every release. Whenever you make a mistake, add an item to the checklist to catch it next time. Here is a delightfully meta checklist for checklists.

Write release notes

Customers are entitled to know what changes are in a release before they decide whether to install it. So write some release notes describing the changes. Use screen captures and/or videos, where appropriate, to break up the text. Release notes can also be very useful for yourself later on.

Email customers whose issues you have fixed

Whenever I record a customer bug report or a feature request, I also record the email of the customer. I then email them when there is a release with a fix. It seems only polite when they have taken the effort to contact me. But it also encourages them to report bugs and suggest features in future. I will also let them access the release before I make it public, so they can let me know if there are any problems with the fix that I might not have spotted.

Don’t force people to upgrade

Don’t force customers to upgrade if I don’t want to. And don’t nag them every day if they don’t. A case in point is Skype. It has (predictably) turned from a great piece of software into a piece of crap now that Microsoft have purchased it. Every release is worst than the last. And, to add insult to injury, it just keeps bleating at me to upgrade and there doesn’t seem to be any way to turn off the notifications.

Don’t promise ship dates

If you promise a ship date and you get your estimate wrong (which you will) then either:

  • You have ship software that isn’t finished; or
  • You miss your ship date

Neither are good. So don’t promise ship dates. I never do and it makes my life a lot less stressful.  It’s ready when it’s ready. I realize that some companies with investors, business partners and large marketing departments don’t have that luxury. I’m just glad that I am not them.

Inform existing customers of the release

There isn’t much point in putting out releases if no-one knows about them. By default my software checks an XML file on my server weekly and informs the customer if a new update is available. I also send out a newsletter with each software release. I generally get a spike in upgrades after each newsletter.

Don’t release too often

Creating a stable release is a lot of work, even if you manage to automate some of it. The more releases you do, the higher percentage of your time you will spend testing, proof reading and updating your website.

Adobe Acrobat seems to go through phases of nagging at me almost daily for updates. Do I think “Wow, I am so happy that those Adobe engineers keep putting out releases of their useful free software”? No. I hate them for it. If you have an early stage product with early-adopters, they may be ok with an update every few days. But most mainstream customers won’t thank you for it.

Don’t release too infrequently

Fixing a bug or usability issue doesn’t help the customer until you ship it. Also a product with very infrequent updates looks dead. The appropriate release frequency will vary with the type of product and how complex and mature it is.

Digitally sign your releases

Digital certificates are a rip-off. But unsigned software makes you look like an an amateur. I am wary of downloading any software that isn’t digitally signed. Apple now prevents you downloading unsigned software by default.  Signing is just an extra line in your build script. It is a bit tedious getting a digital certificate though, so get one that lasts several years.

Check your binaries against major anti-virus software

Over zealous anti-virus software can be a real headache for developers of downloadable software. So it is worth checking if your release is likely to get flagged. You can do this using free online resource virustotal.com. If you are flagged, contact the vendor and ask them to whitelist you.

‘The perfect is the enemy of the good’

Beware second system effect. If you wait for perfection, then you will never ship anything. As long as this release is a significant improvement on the last release, then it is good enough to ship.

Pace yourself

Creating a release is exhausting. Even maths, physics and software prodigy Stephen Wolfram of Mathematica says so:

I’ve led a few dozen major software releases in my life. And one might think that by now I’d have got to the point where doing a software release would just be a calm and straightforward process. But it never is. Perhaps it’s because we’re always trying to do majorly new and innovative things. Or perhaps it’s just the nature of such projects. But I’ve found that to get the project done to the quality level I want always requires a remarkable degree of personal intensity. Yes, at least in the case of our company, there are always extremely talented people working on the project. But somehow there are always things to do that nobody expected, and it takes a lot of energy, focus and pushing to get them all together.

So look after yourself. Make sure you get enough sleep, exercise and eat healthily. Also things may be at their most intense straight after the release with promotion, support, bug fixing etc. So it may be a good idea to take a day or two off before you send the release out.

Don’t release anything just before you go away

There is always a chance a new release is going to mess things up. If you are a one-man band like me, you really don’t want to make a software release just before you go away on holiday or to a conference. Wait until you get back!

Fix screwups ASAP

We all make mistakes from time to time. I recently put out a release of my card planning software, Hyper Plan, that crashed on start-up on some older versions of macOS. Oops. But I got out a release with a fix as soon as I could.

Treat yourself after a release

Releases are hard work. A successful release deserves a treat!


Anything I missed?