Migrating from GitHub Actions to SourceHut Builds
Faster, more ethical, no AI, and EU-based.
After a couple of years running Gitea and Forgejo, I moved my private repos back to GitHub, because my instance was DDoS'd a couple of times and I found myself spending more time than I had wanted upgrading and maintaining it.
I didn't like it, and soon after they started pushing hard for Copilot and AI everywhere, I started looking for alternatives again. Codeberg became the obvious choice for mirroring public repos (I'm still in the process of doing this), but their terms don't allow private, non-FOSS projects, so I eventually chose SourceHut for those, and I've been a very happy customer for a few months, now!
I'd like to share how I migrated a couple of Github Actions for a Deno app with a docker compose based deploy via SSH from GitHub to SourceHut Builds, where I've got a ton more control (they're also faster and run closer to my infrastructure in EU)!
Hopefully this will help someone else with a similar problem.
Here's a sample .github/workflows/deploy.yml file I used to have:
name: Deploy
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Configure SSH
run: |
mkdir -p ~/.ssh/
echo "$SSH_KEY" | tr -d '\r' > ~/.ssh/server.key
chmod 600 ~/.ssh/server.key
cat >>~/.ssh/config <<END
Host server
HostName host.example.com
User root
IdentityFile ~/.ssh/server.key
StrictHostKeyChecking no
END
cat ~/.ssh/config
env:
SSH_KEY: ${{ secrets.SERVER_SSH_KEY }}
- name: Deploy via SSH
run: ssh server 'cd apps/example && git pull origin main && git remote prune origin && docker system prune -f && docker compose up -d --build && docker compose ps && docker compose logs'
And here's the new .builds/deploy.yml file:
submitter:
git.sr.ht:
enabled: true
allow-refs:
- refs/heads/main
secrets:
- <SSH Key UUID>
image: alpine/latest
tasks:
- configure_ssh: |
cat >>~/.ssh/config <<END
Host server
HostName host.example.com
User root
IdentityFile ~/.ssh/<SSH Key UUID>
StrictHostKeyChecking no
END
cat ~/.ssh/config
- deploy_via_ssh: |
ssh server 'cd apps/example && git pull origin main && git remote prune origin && docker system prune -f && docker compose up -d --build && docker compose ps && docker compose logs'
And the .github/workflows/test.yml file (make test calls deno test and a few other deno lint/format/check commands):
name: Run Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: denoland/setup-deno@v2
with:
deno-version-file: .dvmrc
- run: |
make test
And the respective new .builds/test.yml file:
submitter:
git.sr.ht:
enabled: true
allow-refs:
- refs/heads/main
secrets:
- <SSH Key UUID>
image: ubuntu/lts
tasks:
- test: |
sudo apt-get update && sudo apt-get install -y curl unzip make
curl -fsSL https://deno.land/install.sh | sh -s v$(cat repo-name/.dvmrc)
export PATH="$HOME/.deno/bin:$PATH"
cd repo-name
make test
As you can see, they're mostly similar, but the subtle differences still took me some iterations to get the right Deno setup (which I do via .dvmrc), for example. The SSH Key is necessary on the second file in order to be able to check out the private repo. If it's public, you won't need that.
It's also possible there are improvements I can make to these, which I'm missing, so if you know of any, please let me know.
Thank you for your attention and kindness. I really appreciate it!