Neil Macy

How I Build This Website

Over the last year or so I've found myself using my phone far more often than my iPad or Mac. For a while this was mainly for the inevitable Twitter doomscrolling. But I wanted to move away from that. As well as improving what I was reading, I wanted to write things that are more thoughtful than tweets. I already had this site, and I realised I had the chance to play with some mobile apps that could help me to publish posts from my phone.

I use GitHub to store the source code for this website. After some research into how I could use my phone to write for the site, I realised I could also experiment with GitHub Actions, a newish (well, from 2018) CI option available in GitHub that I hadn’t really looked at yet, to deploy it.


I often start by jotting down random ideas in Apple Notes, but I start writing the actual posts in Markdown using Obsidian. I really like it because it keeps the writing process really simple. It's just great for writing Markdown, and I like that it shows me the raw file rather than trying to make it look nice with auto-formatting. While I keep most of my personal notes in Apple Notes, I really like Obsidian for writing.

Once an article is ready to be published, I upload it using the Shortcuts app. I have a nice shortcut that lets me share an article from Obsidian, add the metadata that my site needs to render the article preview, and pushes it to the project's repo on GitHub.

I have the website's git repo stored locally in Working Copy. Working Copy is a good enough git client. It has great support for Shortcuts, but the UI is a bit muddy for my liking. I’d rather have a command line interface for git, but in the absence of that on iOS, I'd prefer a GUI that was less awkward to navigate. Fork, Tower and GitHub Desktop, for example, are all good desktop git clients, and for my liking, Working Copy doesn't match up. But it's the best I've found and it does work.


The site is built on Publish, John Sundell’s static website builder. It uses Swift and Markdown to generate the site. Now that I have the template for the site set up, I never touch any traditional web language like HTML or JavaScript for this site. (My only complaint is that it doesn't support Markdown footnotes. Paradoxically, this comment would have been better as a footnote. But if it was possible, this comment wouldn't exist.)

GitHub Actions

I use two repos on GitHub to publish the site. The main one stores the source code for the project, and the other stores the generated output - the actual static website code. But I never touch the output repo directly. When I want to post something, I write the Markdown file in Obsidian, and push it to the main project, using Shortcuts. When I push to a particular branch, a GitHub Action is triggered that uses Publish’s deploy mechanism to build the site, and pushes that code to the second git repo. The Shortcut that I use is configured to push to that branch by default.

Digital Ocean Apps

The final step is getting the static site from the second git repo onto a webserver somewhere. I was previously hosting it on a Digital Ocean droplet, and I had thought to write a script to pull updated code from my output repo and deploy it for me. Luckily, Digital Ocean Apps launched a little while ago, which saves me all of that trouble.

For a static site like this one, Digital Ocean Apps is incredibly useful. I just connected Digital Ocean with my GitHub account, and was given a drop down list of my repositories. I chose the site output repo, and it was recognised as a static site. Digital Ocean did all the work of setting up the server, I just had to set up a CNAME record on my DNS server to be able to use my domain.

The Full Flow

  1. Write the article as a Markdown file in Obsidian.
  2. Run a Shortcut to save that Markdown file in my site's main git repo, and push it to GitHub, using Working Copy.
  3. Run a GitHub Action to recompile my static website whenever the main repo is updated, and push that compiled website to the output repo.
  4. Digital Ocean Apps updates my site whenever the output repo is updated.

What’s Missing

So I can now write for my website, build it, and deploy it, using my iPhone. What I can’t do yet is run a local webserver to test it before deploying, and this is the main reason why I still only use my Mac for bigger changes to the site, like structural changes or CSS changes. If you have any tips for running a local webserver on an iPhone, or working around that somehow, let me know!


These should have been footnotes, but Publish doesn't support them. I briefly considered replacing Publish, but that would render this post pointless as I'd need to completely change my process for publishing this site, and footnotes aren't that important to me!

A(nother) Problem With Publish

One undocumented part of the process of generating a site with Publish is the generate step itself. This, as you can tell from the name, takes the Swift and Markdown code and generates the HTML website. When you run Publish run locally to test the site, the generate step runs implicitly, before it’s deployed to a local webserver. And of course, when I was doing this all on my Mac, I would run locally before deploying, so I never came across this issue. So when I only ran the deploy stage in my GitHub Action, I ended up with an empty output repository because nothing was being compiled. Not ideal! Simply running the generate step before the deploy step fixed things though.

A Problem With GitHub Actions

Pushing the compiled code to my second, output, repo, wasn’t quite as simple as I'd hoped it would be. Connecting my GitHub Action up to the output repo required generating a deploy key for the output repo, since the push isn’t happening on a server with my ssh key. Given the GitHub Action is running under my GitHub user, and moving code between two of my GitHub repositories, it was a bit surprising that I had to generate a deploy key, but once that was set up it worked with no more issues.

Published on 3 January 2022