cassie ink

Friendship ended with GitHub

friendship-ended-with-github

Since last year, this blog has been running on Hugo. For a while, I used a repository on GitHub that would build and deploy to GitHub Pages. Microsoft is currently targeted by the BDS campaign, which is enough of a reason to minimize or outright eliminate my use of their services (even free ones). GitHub also has a contract with ICE and has whole-heartedly embraced AI, which means anything — including my shitty code and nonsensical ramblings — on their platform is fed to Copilot. Suffice to say, there are a number of reasons to move away from it.

I first moved to 32bitcafe’s Gitea instance and wanted to use Cloudflare Pages to serve the site. Unfortunately, Cloudflare Pages (now called Workers, I think?) only supports GitHub and GitLab. GitLab is also pandering to AI trends and isn’t truly open source, and I found its interface pretty confusing, so I settled for just mirroring from 32bitcafe to GitHub and linking that to Cloudflare. I figured I would revisit the problem when I had more time and knowledge of the alternatives.

This was always a temporary solution, though — as far as I know Cloudflare doesn’t have any humanitarian caveats, but they’re still a giant corporation that controls the portion of the web that Amazon doesn’t. What happens when Cloudflare has an outage? How will people read my very important and timely thoughts on my recent Bandcamp purchases?

Naty did a big write up about how she left GitHub Pages and now deploys to Bunny.net. I already use Bunny to serve media for this site (images, mostly) and my defunct podcasts, so that seemed appealing. But Bunny felt a little bit like taking a machine gun to a knife fight, so I wasn’t totally sold on it as my next step. Also, 32bitcafe doesn’t have an Actions Runner available1, so I would have to move to my repo elsewhere.

Then, a few weeks ago, omg.lol launched source.tube, their new code forge. I’ve been paying for omg.lol’s services for over a year now, so this seemed like the perfect opportunity. I moved my repo from 32bitcafe to source.tube shortly after the launch, but they didn’t immediately have an Actions Runner available, so I continued to mirror the GitHub then deploy with Cloudflare Pages.

The Actions Runner finally became available, so I finally sat down today to sort things out. Here’s how it works:

I cobbled my build script together from a template for Hugo that would deploy to a web server; that, shockingly, did not immediately work, even with my amateurish modifications. I eventually combined the one I originally found online2 with Nico Einsidler’s.

 1name: Hugo Deploy
 2run-name: cassie is testing out Actions 🚀
 3on:
 4  push:
 5    branches:
 6      - master
 7
 8jobs:
 9  deploy:
10    runs-on: docker
11    steps:
12      - uses: actions/checkout@v4
13        with:
14          submodules: true # Fetch Hugo themes (true OR recursive)
15          fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
16      - name: setup Go
17        uses: actions/setup-go@v5
18        with:
19          go-version: "1.25.1"
20      - name: setup Hugo
21        uses: https://github.com/peaceiris/actions-hugo@v3
22        with:
23          hugo-version: "latest"
24          extended: false
25      - name: build site
26        run: hugo --minify
27
28      - name: Deploy to Server
29        uses: https://github.com/wlixcc/SFTP-Deploy-Action@v1.2.6
30        with:
31          username: '${{ secrets.NFSN_USERNAME }}'
32          server: '${{ secrets.NFSN_HOSTNAME }}'
33          local_path: './public/*'
34          remote_path: '/home/public/'
35          password: '${{ secrets.NFSN_PASSWORD }}'
36          port: '22'
37          sftp_only: true
38          
39      - run: echo "🍏 This job's status is ${{ job.status }}."

The initial build and deploy took a long time, but I believe future ones should go faster3 as the script should only upload the content that’s been updated since the last commit (not the case — see the footnote).

If you’re reading this post, you made it! I’m no longer dependent on Microsoft at all. I just push my commits to source.tube (either from obsidian-git, VSCodium, or GitSync) which then builds the site to the /public directory and deploys that to NearlyFreeSpeech (though you could use any web host). The site is still proxied through Cloudflare at the moment, but I might change that in the future — I think I’m planning to slowly move my domains to Porkbun. Once I resolved the DNS nightmares, it all seemed to work. I’ll keep monitoring the site for a while and then eventually port all my others over (which are still mirroring to GitHub and being built by Cloudflare).


The puke emoji in the header was designed by OpenMoji – the open-source emoji and icon project. License: CC BY-SA 4.0


  1. I asked about this in the 32bitcafe Discord server; it is a time and resources issue, which is totally understandable. 32bitcafe, as far as I know, runs entirely off user donations and volunteer time, so I don’t begrudge them at all for not supporting what is probably a niche use case (as their Gitea instance doesn’t seem to have many people on it). ↩︎

  2. I’d link to the source but I can’t find it among the legions of googling I did about this. ↩︎

  3. I was originally using wangyucode/sftp-upload-action and switched to wlixcc/SFTP-Deploy-Action because I found it was a lot faster (~9 mins for each rebuild compared to ~3). It seems the latter can do more than one directory/file at once. It would be nice to only sync the files and directories with changes, but the script I tried that can do that requires lftp, which I don’t think the source.tube runner currently supports. I can wait three minutes. ↩︎