February 7, 2020

Deploying static sites with GitHub Actions and Netlify

…and a hack to turn that PHP site into a static one


For the last few months,56k.cloud has been going through a rebranding process, that included a brand-new website developed by the awesome team at Twotwentytwo. The finished product that they have received was a site developed in Php with some Node.js built assets. But internally we have decided that we really want a static site and to keep using Netlify as everyone has been very happy with it.

The solution

Because the website’s code was already hosted on GitHub, GitHub’s new Actions feature seemed like the best fit for their CI / CD needs: it supports all types of steps that are required and it is already baked into GitHub, I just needed to enable the feature.

The steps

After enabling actions on the website’s GitHub repo, I could get to work at defining theworkflow, in GitHub’s lingo, what other solutions would call a pipeline. The first step was to create a .github/workflows/main.yml that would hold this deploy-to-Netlify workflow.

The workflow .yml needs to have a starting header that will define things like its name, what environment to run on ubuntu-latest or on which actions it should trigger. The decision was made that only pushes to the master branch would trigger this workflow:

          - master

          name: Build and deploy the 56k.cloud website
          runs-on: ubuntu-latest


Now I could start the workflow by checking out the Git repository and installing the tools that are needed, in this case Php and Node.js:

            - name: Checkout
              uses: actions/checkout@v1
            - name: Setup Node
              uses: actions/setup-node@v1
                node-version: '11.x'
            - name: Setup PHP
              uses: shivammathur/setup-php@v1
                php-version: '7.4'

The next step is to install the NPM modules required to generate the static assets and actually generate them:

          - name: Install the site dependencies
            run: npm install
          - name: Build the site static assets
            run: npm run build

Here comes the ‘hackish’ part where I turn this site into a static one. This is achieved by running a Php development web server in the pipeline, in the background that serves the Php code plus the static assets generated the previous step. Then I used the classic and always useful wget to crawl this website and save the HTML content locally:

          - name: Start the PHP dev server in the background
            run: nohup php -S > /dev/null 2>&1 &
          - name: Crawl the website to get our nice HTML files
            run: mkdir output && cd output && wget -k -K -E -r -p -N -F -nH -q http://localhost:8080/

Now I need to copy the previously built static assets in the output directory and do a bit of cleanup because wget will save some of those HTML files with links containing http://localhost:8080/. I wanted to remove that reference to localhost and leave all the links relative, so the HTML files can be hosted anywhere:

          - name: Copy the right static files
            run: |
              cp -r ./dist/* ./output/dist/
              cp -r ./static/* ./output/static/
          - name: Find all artifacts from Wget and clean them up
            run: cd output && find ./ -type f -exec sed -i 's/http\:\/\/localhost\:8080//g' {} \;

At this point in the workflow I had an output directory that contains a static, cleaned up, website. I just needed to deploy it to Netlify! This step can be easily done by using Netlify’s CLI. Before defining this step, you need to make sure you have defined a new site in Netlify’s Web UI from where you can get your site ID that you need here and you have generated an Auth token for your user (the steps can be found in Netlify’s CLI documentation).

          - name: Install the Netlify CLI
            run: npm install netlify-cli -g
          - name: Deploy the website
            run: netlify deploy --prod --dir ./output/ --site=<site_id> --auth=<auth_token> --timeout=600 --message "Deployed on $(date)"

That’s it! Save the workflow file .yml file, push and commit it to GitHub and it should trigger a GitHub action that will do all the work for you from now on and regenerate and redeploy the website at every commit to the master branch.