Skip to content
Netlify Build Plugins. Join the early access beta πŸ‘‰
JavaScript Shell
Branch: master
Clone or download
Latest commit 328ff1f Nov 12, 2019

README.md


Coverage Status Build

Netlify build is the next generation of CI/CD tooling for modern web applications.

Sign up for the private beta

Demo video and slides. See also example guide here in Creating and using your first Netlify Build Plugin.

Expand Table of Contents

Background

During a site build, there are a variety of things happening under the hood.

This is a simplified view of a typical build life cycle:

  1. Netlify clones your repo & looks for diffs
  2. Dependencies are install in the project
  3. We run your build command
  4. Files & dependencies are cached
  5. Finally, your site is deployed to the web!

Historically, when connecting your site to Netlify, we ask for the build command (step 3 above) and will run through this process. This works great for most use cases & will continue to do so πŸ˜ƒ

For builds that require a little more flexibility, we are introducing a programatic interface on top of these build lifecycle steps to allow users to customize this flow.

Netlify Build is designed to support any kind of build flow and is extendable to fit any unique project requirements.

How it works

Builds are controlled by a series of lifecycle events that plugins & configuration hook into.

The build lifecycle can be extended in two ways:

  1. Adding lifecycle steps to build.lifecycle in your config file
  2. Installing pre-packaged plugins

1. Extending via config

Inside the netlify config file, you can attach lifecycle commands to a new property build.lifecycle.

build:
  publish: my-dist-folder
  # Run this lifecycle during build
  lifecycle:
    init:
      - npm run thing
      - echo "much wow"
    preBuild: curl download-static-content
    build: npm run build
    postBuild:
      - npx generate-sitemap

2. Extending via plugins

Netlify Plugins are installable packages that extend the functionality of the netlify build process.

They can be installed from npm or run locally from relative path in your project.

# Config file `plugins` defines plugins used by build.
plugins:
  - type: ./local/path/to/plugin-folder
    config:
      optionOne: 'hello'
      optionTwo: 'there'
 - type: plugin-from-npm
   config:
     optionOne: 'neat'
     arrayOfValues:
      - david@netlify.com
      - jim@netlify.com

Netlify plugins can be found on npm by searching for keywords:netlify-plugin.

Lifecycle

The build process runs through a series of lifecycle events. These events are the places we can hook into and extend how the Netlify build operates.

Lifecycle hook Description
⇩ β€β€β€Ž β€β€β€Ž β€β€β€Ž init β€β€β€Ž β€β€β€Ž β€β€β€Ž Runs before anything else
⇩ β€β€β€Ž β€β€β€Ž β€β€β€Ž getCache β€β€β€Ž β€β€β€Ž β€β€β€Ž Fetch previous build cache
⇩ β€β€β€Ž β€β€β€Ž β€β€β€Ž install β€β€β€Ž β€β€β€Ž β€β€β€Ž Install project dependencies
⇩ β€β€β€Ž β€β€β€Ž β€β€β€Ž preBuild β€β€β€Ž β€β€β€Ž β€β€β€Ž Runs before functions & build commands run
⇩ β€β€β€Ž β€β€β€Ž β€β€β€Ž build β€β€β€Ž β€β€β€Ž β€β€β€Ž Build commands are executed
⇩ β€β€β€Ž β€β€β€Ž β€β€β€Ž functionsBuild β€β€β€Ž β€β€β€Ž β€β€β€Ž Build the serverless functions
⇩ β€β€β€Ž β€β€β€Ž β€β€β€Ž postBuild β€β€β€Ž β€β€β€Ž β€β€β€Ž Runs after site & functions have been built
⇩ β€β€β€Ž β€β€β€Ž β€β€β€Ž package β€β€β€Ž β€β€β€Ž β€β€β€Ž Package & optimize artifact
⇩ β€β€β€Ž β€β€β€Ž β€β€β€Ž preDeploy β€β€β€Ž β€β€β€Ž β€β€β€Ž Runs before built artifacts are deployed
⇩ β€β€β€Ž β€β€β€Ž β€β€β€Ž saveCache β€β€β€Ž β€β€β€Ž β€β€β€Ž Save cached assets
πŸŽ‰ β€β€β€Ž finally β€β€β€Ž β€β€β€Ž β€β€β€Ž Runs after anything else

The Lifecycle flows the events in order and executes and their pre & post counterparts.

pre happens before a specific event.

post happens after a specific event.

      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
      β”‚      pre      β”‚     event      β”‚       post       β”‚
      β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
      β”‚               β”‚                β”‚                  β”‚
      β”‚               β”‚                β”‚                  β”‚
...   β”‚   preBuild    β”‚     build      β”‚    postBuild     β”‚   ...
      β”‚               β”‚                β”‚                  β”‚
      β”‚               β”‚                β”‚                  β”‚
      └────────────────                β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

      ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ β–Ά

                        event flow

lifecycle.init

init - Runs before anything else

Using init

1. Using with a Plugin

Below is an example plugin using the init hook

module.exports = function myPlugin(pluginConfig) {
  return {
    init: () => {
      console.log('Do thing on init step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    init:
      - echo "Do thing on init step"

lifecycle.getCache

getCache - Fetch previous build cache

Using getCache

1. Using with a Plugin

Below is an example plugin using the getCache hook

module.exports = function myPlugin(pluginConfig) {
  return {
    getCache: () => {
      console.log('Do thing on getCache step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    getCache:
      - echo "Do thing on getCache step"

lifecycle.install

install - Install project dependencies

Using install

1. Using with a Plugin

Below is an example plugin using the install hook

module.exports = function myPlugin(pluginConfig) {
  return {
    install: () => {
      console.log('Do thing on install step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    install:
      - echo "Do thing on install step"

lifecycle.preBuild

preBuild - Runs before functions & build commands run

Using preBuild

1. Using with a Plugin

Below is an example plugin using the preBuild hook

module.exports = function myPlugin(pluginConfig) {
  return {
    preBuild: () => {
      console.log('Do thing on preBuild step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    preBuild:
      - echo "Do thing on preBuild step"

lifecycle.build

build - Build commands are executed

Using build

1. Using with a Plugin

Below is an example plugin using the build hook

module.exports = function myPlugin(pluginConfig) {
  return {
    build: () => {
      console.log('Do thing on build step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    build:
      - echo "Do thing on build step"

lifecycle.functionsBuild

functionsBuild - Build the serverless functions

Using functionsBuild

1. Using with a Plugin

Below is an example plugin using the functionsBuild hook

module.exports = function myPlugin(pluginConfig) {
  return {
    functionsBuild: () => {
      console.log('Do thing on functionsBuild step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    functionsBuild:
      - echo "Do thing on functionsBuild step"

lifecycle.postBuild

postBuild - Runs after site & functions have been built

Using postBuild

1. Using with a Plugin

Below is an example plugin using the postBuild hook

module.exports = function myPlugin(pluginConfig) {
  return {
    postBuild: () => {
      console.log('Do thing on postBuild step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    postBuild:
      - echo "Do thing on postBuild step"

lifecycle.package

package - Package & optimize artifact

Using package

1. Using with a Plugin

Below is an example plugin using the package hook

module.exports = function myPlugin(pluginConfig) {
  return {
    package: () => {
      console.log('Do thing on package step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    package:
      - echo "Do thing on package step"

lifecycle.preDeploy

preDeploy - Runs before built artifacts are deployed

Using preDeploy

1. Using with a Plugin

Below is an example plugin using the preDeploy hook

module.exports = function myPlugin(pluginConfig) {
  return {
    preDeploy: () => {
      console.log('Do thing on preDeploy step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    preDeploy:
      - echo "Do thing on preDeploy step"

lifecycle.saveCache

saveCache - Save cached assets

Using saveCache

1. Using with a Plugin

Below is an example plugin using the saveCache hook

module.exports = function myPlugin(pluginConfig) {
  return {
    saveCache: () => {
      console.log('Do thing on saveCache step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    saveCache:
      - echo "Do thing on saveCache step"

lifecycle.finally

finally - Runs after anything else

Using finally

1. Using with a Plugin

Below is an example plugin using the finally hook

module.exports = function myPlugin(pluginConfig) {
  return {
    finally: () => {
      console.log('Do thing on finally step')
    },
  }
}

After creating the plugin, add into your Netlify config file under plugins

plugins:
  - type: ./path/to/plugin
    config:
      foo: bar

2. Using with via build.lifecycle

build:
  lifecycle:
    finally:
      - echo "Do thing on finally step"

Configuration

Configuration can be written in toml, yml, json, or json5.

Example:

# Config file `plugins` defines plugins used by build. Plugins are optional
plugins:
  - type: ./local/path/to/plugin-folder
    config:
      optionOne: 'hello'
      optionTwo: 'there'
  - type: plugin-from-npm
    config:
      optionOne: 'neat'
      arrayOfValues:
        - david@netlify.com
        - jim@netlify.com

# Inline `build.lifecycle` steps can be defined
build:
  lifecycle:
    init:
      - npm run foo
      - export VALUE=lol
      - echo "much wow"
    getCache:
      - echo 'curl custom cache'
    preBuild: echo "${env:privateKey}"
    build: |
      echo 'Hello Netlify Build!'
      npm run build

Configuration now supports environment variables & secrets.

To reference an environment variable in Netlify config:

foo: ${env:MY_ENV_VAR}

Plugins

Netlify Plugins extend the functionality of the netlify build process.

Plugins are POJOs (plain old JavaScript objects) that allow users to hook into the different lifecycle steps happening during their site builds.

For example, hooking into the preBuild step to run something before your build command. Or the postBuild hook for running things after your site build has completed.

{
  name: 'netlify-plugin-awesome',
  init: () => { /* Run custom logic at beginning of build */ }
  preBuild: () => { /* Run custom logic before build happens */ },
  finally: () => { /* Run custom logic at the end of the build */ }
  // ... etc
}

Here is an example:

/* file ./plugins/my-plugin/index.js */
module.exports = function exampleOne(pluginConfig) {
  return {
    name: 'netlify-plugin-awesome',
    init: () => {
      console.log('Run custom logic at beginning of build')
    },
    preBuild: () => {
      console.log('Run custom logic before build happens')
    },
    postBuild: () => {
      console.log('Run custom logic after build happens')
    },
    finally: () => {
      console.log('Run custom logic at the end of the build')
    },
  }
}

To use this plugin, define the plugins key in your Netlify config file.

build:
  functions: src/functions
  publish: build
  command: npm run build

# Netlify build plugins
plugins:
  # Path to plugin. Can be local relative path or reference to node_modules
  - type: ./plugins/my-plugin/
    config:
      a: hello
      b: goodbye

What can plugins do?

Plugins can do a-lot and we are excited what the JAMstack community will build!

Here are some examples:

  • @netlify/plugin-lighthouse to automatically track your lighthouse site score between deployments
  • @netlify/plugin-sitemap to generate sitemaps after build
  • @netlify/plugin-notify to automatically wired up build notifications
  • @netlify/plugin-no-more-404 fail build or warn if prior .html files disappear without corresponding Netlify redirects.
  • @netlify/plugin-axe to automatically audit site for accessibility issues
  • @netlify/plugin-encrypted-files to encrypt files in source, but to decrypt them locally and for the build, so that you can do partial open source sites without leaking announcements or private info.
  • @netlify/plugin-twiliosms text your boss every time you deploy so they know you're working - example guide here in Creating and using your first Netlify Build Plugin
  • @netlify/plugin-svgoptimizer to automatically optimize all SVGs in a directory when the site is built
  • netlify-plugin-cypress to automatically run integration tests
  • netlify-plugin-tweet-new-post to automatically share new content via twitter on new publish
  • ... the sky is the limit 🌈

CLI commands

Like Netlify dev, Netlify build runs locally and in the remote CI context

To execute your build locally, run the following CLI command:

netlify build

It's also possible to "try before you buy" and test out the build flow before executing any code with the dry run flag.

The --dry flag will output everything that happens in the build flow without executing the plugin lifecycle methods.

To execute a test run of the build locally, run the following CLI command:

netlify build --dry

Contributors

Thanks for contributing!

Please see CONTRIBUTING.md for instructions on how to set up and work on this repo itself.

You can’t perform that action at this time.