Netlify with Github Actions

Wednesday, May 31, 2023

I am bit late to the party but for sometime have been thinking to get my hands dirty with the new front-end frameworks which are built on top of react. NextJs is one of the new frameworks which did amaze me especially with the ability to do both static and dynamic rendering on per page basis, this in my opinion is quite extraordinary. Also this is now really useful for starting up a project that would start with a small static site and grow into a bigger dynamic beast.

I started with building a basic NextJs site hosting it on Netlify cause why not, and wanted to use github-actions to deploy as I didn’t wanted to use the netlify’s continous deployments as those although quite easy to setup doesnot allow me to control everything and had to give permissions for netlify to update my repository which I didn’t really wanted to give.

The setup I described above took some tinkering as there aren’t any good articles that do exactly the same. there’s one quite good article but uses an older way to deploy. The function next-on-netlify is not supported now thus these links were not really useful. There’s other one here.

There are a few other github-actions created by different users. These although good aren’t really what I needed.

I thus moved on to build the NextJs + github-actions + Netlify solution myself. I used the basic netlify/actions/cli@master action to deploy my site onto netlify. My yaml file to deploy a branch-build looks as below :

name: Main workflow

on:
  push:
    branches:
      - develop

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      # Cache node modules and next folder
      - name: ๐Ÿ“ฌ Caching
        uses: actions/cache@v2
        with:
          path: |
            **/node_modules
            ${{ github.workspace }}/.next/cache
          key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}

      - name: Use Node.js 18.x
        uses: actions/setup-node@v1
        with:
          node-version: 18.x
          
      - name: ๐Ÿงฐ Install dependencies
        run: npm install

      - name: ๐Ÿ“ฆ Build project
        run: npm run build --if-present

      # - name: ๐Ÿงน Run lint
      #   run: npm run lint

      # - name: ๐Ÿ› Run tests
      #   run: npm run test

      # Deploy to Netlify with a personalized message
      - name: ๐Ÿš€ Deploy to Netlify
        id: deploy-netlify
        uses: netlify/actions/cli@master
        env:
          NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
          NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
        with:
          args: deploy --alias=neeraj -m 'v${{ steps.package-version.outputs.current-version}} ใƒป ${{ github.head_ref }}' --dir=build

Above you would see I used alias=neeraj to be able to have a reliable preview url for my website, this was needed to make sure I am able to see what I deploy on a branch and is that good to go to production branch. The import bits were to configure the next.config.js properties correctly in order to have the website correctly rendered on the netlify url.

/** @type {import('next').NextConfig} */
const nextConfig = {
}

const isProd = process.env.NODE_ENV === 'production'
module.exports = {
    assetPrefix: isProd ? 'https://neeraj--<site-name>.netlify.app': '',
    distDir: 'build',
    output: 'export',
    images: {unoptimized: true},
}

Above options took the most time to get right. If you see my distDir is different from the regular .next. Also setting up the assetPrefix was quite importatnt to make sure the requirement for chunks is rendered correctly. output: export was quite important as that is the option which creates and production ready build. and the images: {unoptimized: true} is needed for hosting static sites as they need all the images as assests.

Apart from above the rest of the site was pretty much the same setup that you would get from npx create-next-app@latest thus won’t be going into the details of it.