2019-12-25
Building Gatsby with GitHub Actions and deploying to Netlify
gatsby, github, actions, netlify, deployment, ci
gatsby, github, actions, netlify, deployment, ci
Netlify introduced build minutes (300 minutes for the free tier, 1000 for the pro account), which limits build time on their site.
Thankfully, Netlify community support has provided a guideline, How can I optimize my Netlify build time?, with many tips.
You can shave off the build time by delegating the build minutes to GitHub Actions by building and deploying directly to Netlify.
I am writing this while learning about GitHub Actions, so let me know should you find any errors. :)
If you want to know more about GitHub Actions, check out the official GitHub Actions documentation.
Refer to Configuring a workflow.
Below is the complete GitHub workflow in YAML for building a Gatsby site, and deploying to Netlify every 2 hours.
1name: Build and Deploy to Gatsby every two hours2
3on:4 # 1. Trigger the workflow every 2 hours5 schedule:6 - cron: "0 */2 * * *"7
8jobs:9 build:10 # 2. Using the latest Ubuntu image11 runs-on: ubuntu-latest12
13 steps:14 # Check out the current repository code15 - uses: actions/checkout@v116 # 3. https://github.com/actions/setup-node#usage17 - uses: actions/setup-node@v118 with:19 node-version: "12.x"20 - run: npm install21 # This triggers `gatsby build` script in "package.json"22 - run: npm run build23 # 4. Deploy the gatsby build to Netlify24 - uses: netlify/actions/cli@master25 env:26 NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}27 NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}28 with:29 # 5. "gatsby build" creates "public" folder, which is what we are deploying30 args: deploy --dir=public --prod31 secrets: '["NETLIFY_AUTH_TOKEN", "NETLIFY_SITE_ID"]'
Deploying to Netlify with Netlify CLI requires a personal access token, NETLIFY_AUTH_TOKEN (and an optional site ID, NETLIFY_SITE_ID).
But You should never expose your API keys, ever, period.
Thankfully, GitHub provides a way to create secret environment variables, which you can pass to the workflow definition.
You now need to declare the environment variables, and pass it to the CLI.
1env:2 NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}3 NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}4with:5 # 5. "gatsby build" creates "public" folder, which is what we are deploying6 args: deploy --dir=public --prod7 secrets: '["NETLIFY_AUTH_TOKEN", "NETLIFY_SITE_ID"]'
Refer to the deploy command on Netlify CLI documentation.
so the configuration above would look like following in command line.
In powershell,
$env:NETLIFY_AUTH_TOKEN='secret'; $env:NETLIFY_SITE_ID='site id'; netlify deploy --dir=public --prod
In bash,
NETLIFY_AUTH_TOKEN='secret' NETLIFY_SITE_ID='site id' && netlify deploy --dir=public --prod
I wasn't aware of an alternative syntax to declare the workflow, and had hard time with passing the secrets.
1workflow "Publish on Netlify" {2 on = "push"3 resolves = ["Publish"]4}5
6action "Publish" {7 uses = "netlify/actions/cli@master"8 args = "deploy --dir=site --functions=functions"9 secrets = ["NETLIFY_AUTH_TOKEN", "NETLIFY_SITE_ID"]10}
GitHub Actions's YAML editor complains that you can't pass an array to the secret, so you need to turn it into a string,
1# 👇 secrets is a string 👇2secrets: '["NETLIFY_AUTH_TOKEN", "NETLIFY_SITE_ID"]'3# not an array.4secrets: ["NETLIFY_AUTH_TOKEN", "NETLIFY_SITE_ID"]
After commiting the workflow file, you can see that the Gatsby was built and deployed to Netlify successfully in the log.
Now the Netlify log shows that it only took 1 second to deploy.
When your Netlify site is linked to your GitHub repository, any source code commit will trigger a build on Netlify.
But You can't unlink GitHub repository from Netlify UI, to prevent an auto-build (unless you create a new site without linking to a repository first).
So you need to go to Netlify community support and request to unlink your site(s).
As an exmaple here is the request for SHANc, which was handled quickly on X-Mas! (🙂👍)
Here is a comparison between liked and unlinked sites.
There is no way to manually trigger workflows, so I made the workflow to run on code "push" initially before making it run on schedule.
1name: Build and Deploy to Gatsby every hour2
3# https://help.github.com/en/actions/automating-your-workflow-with-github-actions/configuring-a-workflow#triggering-a-workflow-with-events4on:5 schedule:6 - cron: '0 */2 * * *'7# https://help.github.com/en/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows#example-using-a-single-event8# 👇 To test, uncomment these and comment three lines above.9# on:10# push:11# branches:12# - master13
14jobs:15 build:16 runs-on: ubuntu-latest17 ...
Check out About workflow events for more triggers.