Command hooks
Use Command Hooks to execute custom scripts before, during, and after Amplify CLI commands (“amplify push”, “amplify api gql-compile”, and more). This allows you to extend Amplify’s best-practice defaults to meet your organization’s specific security guidelines and operational requirements.
Adding a command hook
Place your custom scripts in the amplify/hooks directory and set the script file name to the desired command with a pre or post designation. For example post-add-function.js will execute the script after amplify add function. For more information about the script naming convention, see How to name command hook scripts.
For this example, let's create a hook to ensure that a minimum major Amplify CLI version is used before deployment (amplify push).
Let's add pre-push.js in the amplify/hooks directory with the following contents. Note: You need to create a amplify/hooks folder if your Amplify project was created prior to Amplify CLI version 5.5.0
const fs = require('fs');const parameters = JSON.parse(fs.readFileSync(0, { encoding: 'utf8' }));
// Get the running Amplify CLI major version numberconst currentCLIMajorVersion = parameters.data.amplify.version.split('.')[0]console.log('Amplify CLI major version: ', currentCLIMajorVersion)
const MINIMUM_MAJOR_AMPLIFY_CLI_VERSION = 5console.log('Minimum required Amplify CLI major version: ', MINIMUM_MAJOR_AMPLIFY_CLI_VERSION)
if (currentCLIMajorVersion < MINIMUM_MAJOR_AMPLIFY_CLI_VERSION) { // Non-zero exit code will stop the Amplify CLI command's execution console.log('Minimum CLI version requirement not met.') process.exit(1)} else { console.log('Minimum CLI version requirement met.') process.exit(0)}Next, let's run amplify push:
amplify push----- 🪝 pre-push execution start -----Amplify CLI major version: 5Minimum required Amplify CLI major version: 5Minimum CLI version requirement met.----- 🪝 pre-push execution end -----How to name command hook scripts
To hook into a command, the script file in the amplify/hooks directory should be named with the following naming convention:
pre|post-<command>[-<sub-command>].extension
command(required) - Amplify command.extension(required) - by default.jsand.share mapped to Node.js and Bash. To support more extensions or scripting runtimes, see Adding a custom scripting runtime.sub-command(optional) - Amplify sub-command. Can be used to increase hook specificity. Example:pre-add-authandpre-mock-api.
The following is an exhaustive list of all commands along with their subcommands that are supported by Amplify CLI:
| commands | sub-commands (optional) |
|---|---|
add | all categories (api, auth, etc.)codegenenv |
update | all categories (api, auth, etc.)env |
remove | all categories (api, auth, etc.)env |
push | analytics, api, auth, function, hosting, interactions, storage, xr |
pull | env |
publish | - |
delete | - |
checkout | env |
list | env |
get | env |
mock | api, storage, function |
build | function |
status | notifications |
import | auth, storage, env |
gqlcompile | api |
addgraphqldatasource | api |
statements | codegen |
types | codegen |
Note: Multiple hook scripts with the same filename are not allowed
Access parameters in hook scripts
Command hooks receive two parameters, data and error. Amplify CLI passes parameters to hook scripts as a JSON string through standard input.
data parameter structure
{ "amplify": { "version": String, "environment": { "envName": String, "projectPath": String, "defaultEditor": String }, "command": String, "subCommand": String, "argv": [ String ] }}- amplify
- version - current Amplify CLI version
- environment - current Amplify environment
- envName - current Amplify environment name
- projectPath - path to current Amplify project
- defaultEditor - chosen editor in init step. Example
vscode
- command - hooked Amplify CLI command. Example:
push - subCommand - hooked Amplify CLI subcommand or plugin. Example
auth,env. - argv - list containing the arguments passed to Amplify CLI through the command line
error parameter structure
error is undefined if no error is emitted. Otherwise, it has the following structure:
{ "message": String, "stack": String}- message - the error message emitted by Amplify CLI
- stack - the error stack emitted by Amplify CLI
How to access command hook parameters in Node.js
const fs = require('fs');const parameters = JSON.parse(fs.readFileSync(0, { encoding: 'utf8' }));console.log(parameters.data, parameters.error)How to access command hook parameters in Bash
First, install a JSON parser like jq.
Then, parse the parameters:
parameters=`cat`data=$(jq -r '.data' <<< "$parameters")error=$(jq -r '.error // empty' <<< "$parameters")echo $dataecho $errorHow to conditionally stop an Amplify CLI command execution
To stop the execution of Amplify CLI, the hook scripts can exit with a non-zero exit code.
process.exit(1)exit 1Advanced command hook configurations
You can optionally add hooks-config.json in amplify/hooks to configure custom scripting runtimes or manage external dependencies.
Adding a custom scripting runtime
By default, Node.js and Bash are supported. To support additional runtimes, add extensions to the hooks-config.json file in the amplify/hooks folder.
An example showcasing python runtime support and different runtime settings based on operating system:
{ "extensions": { "py": { "runtime": "python3" }, "js": { "runtime": "~/.nvm/versions/node/v14.17.1/bin/node", "runtime_windows": "node", "runtime_options": ["--require", "./payload.js"], } }}- The keys in the
extensions( js, py ) are values that will be used asextensionin the naming convention used when naming the hook scripts. runtime(required) - symlink (node,python,bash) or path to executable (~/.nvm/versions/node/v14.17.1/bin/node).runtime_windows(optional) - windows specific symlink or path to executable.runtime_options(optional) - Array of cli options to be passed to command hooks specific to runtime.
Managing third-party dependencies
Packages from external package managers like npm can be used in command hooks scripts. In this example, you'll install axios as a dependency for your Node.js hooks.
First, go to the hooks folder and install the axios dependency.
cd amplify/hooksnpm initnpm install axiosNote: If you use command hooks with Amplify Hosting CI/CD pipelines, you also need to have a preBuild step configured to install the hook dependencies:
backend: phases: preBuild: commands: - cd amplify/hooks - npm installfrontend:...Dependency directories and files, such as node_modules, should be added to ignore in hooks-config.json.
{ "ignore": ["node_modules", "build"]}Note: All entries in ignore should follow the .gitignore specification.
You can now use axios in your hook scripts placed in the amplify/hooks directory.
Executing different logic based on environment
When using multi-environment setup you can customize command hooks logic based on data.amplify.environment.envName parameter.
/** * @param data { { amplify: { environment: { envName: string, projectPath: string, defaultEditor: string }, command: string, subCommand: string, argv: string[] } } } * @param error { { message: string, stack: string } } */const hookHandler = async (data, error) => { if (data.amplify.environment.envName === 'prod') { console.log('Executing pre-add-auth hook for prod environment'); } else if (data.amplify.environment.envName === 'dev') { console.log('Executing pre-add-auth hook for dev environment'); }};
const getParameters = async () => { const fs = require("fs"); return JSON.parse(fs.readFileSync(0, { encoding: "utf8" }));};
getParameters() .then((event) => hookHandler(event.data, event.error)) .catch((err) => { console.error(err); process.exitCode = 1; });Using command hooks in Amplify's CI/CD pipeline
Command hooks are executed when CI/CD builds are triggered on Amplify Hosting. To execute hook scripts in the Amplify Hosting, add the hook scripts to the amplify/hooks directory and commit them to your source control.
By default only pre-push and post-push hooks will be executed on builds in Amplify Hosting.
To use scripting runtimes other than Node.js and Bash, see Adding a custom scripting runtime and also update the Build Settings in Amplify Hosting to include the runtime executable.
In this example, you'll add a python hook script running in the Amplify Hosting's CI/CD pipeline:
-
Add the python hook script along with
hooks-config.jsonto the hooks directory.touch amplify/hooks/hooks-config.json -
Navigate to your app in the Amplify Hosting and select App settings > Build settings to update the
preBuildphase to install python....backend:phases:preBuild:commands:- yum install -y python3frontend:... -
Add
python3tohooks-config.jsonand push the change to your source control to trigger the Amplify Hosting build.{"extensions": {"py": { "runtime": "python3" }}} -
You’re all set! The python command hooks will be executed in new CI/CD builds.
Command hook limitations with Amplify Studio
Command Hooks are not executed when updating a backend via Amplify Studio.