Building and deploying on neocities from github

Introduction

While browsing the smaller side of the web I’ve stumbled across several tutorials and writings on how people are deploying and building their websites for neocities. For example DeadRodrick is building with Jekyll and deploying to neocities with github actions with github actions, SCUMSUCK have a similar tutorial and PunkWasp wrote about building with eleventy.

One thing I haven’t been able to find yet is a description on how to set up a more complete pipeline on github actions and since this is the primary focus of my current studies i present this document on how I achieved this.

Who is this for?

This guide is for you if you are maintaining a website on neocities and have a bit familiarity with using git and github and if you’re building your website with a tool like Jekyll. This guide is not a starting point, there are other excellent guides and tutorials out there for you to get started before returning here if the subject appeals to you.

Some resources to get you started

If you decide that this is for you please consider your actions carefully, make sure to have backups of your important data and keep in mind that I’ll most likely won’t be able to assist you. Read the whole thing at least once before you embark on your adventure and: I hope this is informative and useful for you!

The theoretical section

The two tutorials about deploying to neocities linked in the introduction describe how to use github actions to deploy an already built website, that is, you already have the files and could manually upload them at the edit section on neocities as described at the end of the eleventy tutorial.

But both of these steps can be done using github actions. We can code our website locally using Jekyll (or similar) and have them magically built and deployed to neocities when we push or merge our changes to the main branch on github. What we gain by this is that our build and deployment process is well defined and repeatable, it will be done the same way every time (no paw or hand will disrupt it by typos).

Before we start

I will assume that you know how to build your website for production. Since I’ll be using Jekyll, that is JEKYLL_ENV=production bundle exec jekyll build. I’ll also assume that you already have a working .github/workflows/pipeline.yml that you’ve configured to succesfully deploy to neocities.

The practical section

Let’s get started by having github actions run our build command without deploying to neocities, for this we will be using a testing branch test and actions/upload-artifact@v4. This way we can verify that the files we later deploy are what we expect. This is my starting point for .github/workflows/test-pipeline.yml:

name: Test Neocities Deploy

on:
  push:
    branches: [ "test" ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Check out the repository
        uses: actions/checkout@v4

        # More steps here later

      - name: Put the site as an artifact on github
        uses: actions/upload-artifact@v4
        with:
          name: SiteArtifact
          path: ./_site #Build outputs

There are still some steps missing but if you push this it should complete without errors but with the warning that No files were found with the provided path: ./_site. No artifacts will be uploaded.. Let’s add a build step before we’re trying to upload the artifacts. How this step looks will depend on your specific setup but for me it looks like this:

- name: Build the website
  run: JEKYLL_ENV=production bundle exec jekyll build

This time if you push you’ll most likely run into an actuall error: the command could not be run. The environment in which we’re running the pipeline doesn’t come preconfigured for us so we’ll have to fix this ourselves. Again, how this looks will depend on your setup. For my solution I referenced the setup for the Jekyll tutorial I followed. For this step there is some work for you to do but I belive in you, you’ll find the information you need if you search around a bit.

There might be some other things we’re depending on as well, in the case of ruby and jekyll these should be defined in a Gemfile and can be installed with bundle install, this is also a step that we’ll have to include. We’re adding both of these steps before our build step.

Hints and tips

The steps are being run in order from top to bottom, adding this step before building is important. If you're trying this with the eleventy tutorial I think node is what you want. There are many github actions for setting up different environments, the one for you is out there somewhere!

- name: Set up environment
  uses: ruby/setup-ruby@v1
  with:
    ruby-version: '3.1'

- name: Install dependencies
  run: bundle install

When all eventual problems are solved the pipeline should leave us with an artifact that we can inspect and if everything is looking great there’s only one step left: To swap out the upload-artifact step for the deploy-to-neocities step.

- name: Deploy to neocities
  uses: bcomnes/deploy-to-neocities@v2
  with:
    api_token: $
    cleanup: false
    dist_dir: ./_site

Notes and reflections

As with making pancakes there are many different ways to do this, I am no expert and if you have any suggestions I would gladly like to hear them (both in regards to github actions and pancakes). My primary reflection after having set this up is that having a file that defines my dependencies (Gemfile) felt really helpful, to have everything neccessary in one place feels like it will greatly reduce the risk of mismatching environments.

My final file

This is what I ended up using as .github/workflows/pipelin.yml and it is what brought this tutorial to you. Thanks for reading to the end. <3

name: Neocities Deploy

on:
  push:
    branches: [ "main" ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Check out the repository
        uses: actions/checkout@v4
      
      - name: Set up environment
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.1'
      
      - name: Install dependencies
        run: cd ./jekyll && bundle install

      - name: Build the website
        run: cd ./jekyll && \
          JEKYLL_ENV=production bundle exec jekyll build
      
      - name: Deploy to neocities
        uses: bcomnes/deploy-to-neocities@v2
        with:
          api_token: $
          cleanup: false
          dist_dir: ./jekyll/_site