You’ve probably seen this curl command in many articles online: [1]
curl -u admin:admin -F file=@"name of zip file" -F name="name of package" -F force=true -F install=true http://localhost:4505/crx/packmgr/service.jsp
It allows you to upload and install an package to an AEM server. This is can also be used in Jenkins builds to deploy a package after the maven build completes. How about we get a little fancy with a script that will do this for us in a cleaner manner. One that will fail if the package deployment fails and will also fail if the AEM server returns anything but 200:
I added comments everywhere to make this easier to understand, if anything is unclear, let me know in the comment section!
#!/bin/bash # Doc HELP_TEXT=" A shell script to install packages to AEM Params: -f, --file The zip file to instal (cannot be used with -m, --module param) -m, --module The folder name of maven module that produces a zip package (cannot be used with -f, --file param) -h, --host The instance host -p, --port The instance port -u, --user The user name to use for auth Password should be set via env variable: CRX_PASSWORD Set from env variable, default to 'admin' Other variables you can set via environment variables: CRX_USER Set via user argument above, defaults to 'admin' CRX_PORT Set via port argument above, defaults to '4502' CRX_HOST Set via host argument above, defaults to 'localhost' " # if the first arg is "--help", "help" or "-h" print help message and exit if [ $1 = "--help" ] || [ $1 = "help" ] || [ $1 = "-h" ]; then printf "$HELP_TEXT" exit 1 fi # parse params as per: https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash while [[ $# -gt 0 ]] do key="$1" case $key in # parse file argument -f|--file) FILE="$2" shift # past argument shift # past value ;; # parse file argument -m|--module) MVN_MODULE="$2" shift # past argument shift # past value ;; # parse host argument -h|--host) CRX_HOST="$2" shift # past argument shift # past value ;; # parse port argument -p|--port) CRX_PORT="$2" shift # past argument shift # past value ;; # parse user argument -u|--user) CRX_USER="$2" shift # past argument shift # past value ;; # unknown option *) echo "WARNING: unknown option: $1" shift # past argument ;; esac done # use defaults if param was not passed CRX_USER="${CRX_USER:-admin}" CRX_PASSWORD="${CRX_PASSWORD:-admin}" # password should be passed as an env variable CRX_HOST="${CRX_HOST:-localhost}" CRX_PORT="${CRX_PORT:-4502}" # If an module folder name is passed, use that to find the zip package to install if [ ! -z "$MVN_MODULE" ] then if [ -d "$MVN_MODULE" ] then ZIP_PATTERN="$MVN_MODULE/target/*.zip" ZIP_PACKAGES=( $ZIP_PATTERN ) FILE="${ZIP_PACKAGES[0]}" else echo "ERROR: The module folder: $MVN_MODULE does not exist}" exit 1 fi else echo "INFO: no module param was passed. Using file param if exists" fi # sets INSTALL_COMMAND, first arg is the password setInstallCommand(){ # --fai : https://curl.haxx.se/docs/manpage.html#-f fails on server error # -u : user:password for basic auth # -F force=true : force install # -F install=true : install after upload # -F strict=true : fails if package fails to deploy eval "INSTALL_COMMAND='curl --fail -u $CRX_USER:$1 -F file=@$FILE -F name=$FILE -F force=true -F install=true -F strict=true http://$CRX_HOST:$CRX_PORT/crx/packmgr/service.jsp'" } # print command that will be executed, sub password with "*****" setInstallCommand "*****" echo "Executing command: $INSTALL_COMMAND" # Execute command setInstallCommand "$CRX_PASSWORD" eval "$INSTALL_COMMAND"
Copy the code and paste it into a file, call it:
deploy.sh
Make it executable:
chmod +x deploy.sh
Now, let’s explore what we can do with it (You should first copy paste it into the root of your AEM project):
run `./deploy help` to see the help message and all available params:
A shell script to install packages to AEM Params: -f, --file The zip file to instal (cannot be used with -m, --module param) -m, --module The folder name of maven module that produces a zip package (cannot be used with -f, --file param) -h, --host The instance host -p, --port The instance port -u, --user The user name to use for auth Password should be set via env variable: CRX_PASSWORD Set from env variable, default to 'admin' Other variables you can set via environment variables: CRX_USER Set via user argument above, defaults to 'admin' CRX_PORT Set via port argument above, defaults to '4502' CRX_HOST Set via host argument above, defaults to 'localhost'
Let’s say you want to deploy the
./deploy.sh -m ui.apps
Now let’s say you want to deploy it to your local publisher:
./deploy.sh -m ui.apps -p 4503
Wait a sec! What just happened there? We specified the maven module via “-m
ui .apps” the deploy script will then go to the folder `ui .apps/target` and pick the first .zip file it finds and will deploy that. This assumes that your module produces one package, as is often the case.
OK, now let’s say you want to deploy a very specific package in a very specific location in your repo: “packages/my-favorite-package.zip”. You can use -f for that:
./deploy.sh -f packages/my-favorite-package.zip
Now let’s move to Jenkins (or your favorite CD). Things get a little interesting. You have a secret password that you don’t want to share with everyone who can see the build. Fear not! You can use secret environment variables! There are a few ways to do this, which I won’t get into. Instead
Note: you can also specify the username, host and port via CRX_USER, CRX_HOST and CRX_PORT respectively.
Now in your Jenkins build, you can add a post build script that looks like:
./deploy.sh -m ui.apps -u adminusername -h dev-author.mycompany.com -p 4502
If you have more than one module that produces packages you can keep calling the deploy script. For example, you want to deploy both
./deploy.sh -m ui.apps -u adminusername -h dev-author.mycompany.com -p 4502 ./deploy.sh -m ui.apps -u adminusername -h dev-publish.mycompany.com -p 4503 ./deploy.sh -m ui.content -u adminusername -h dev-author.mycompany.com -p 4502 ./deploy.sh -m ui.content -u adminusername -h dev-publish.mycompany.com -p 4503
Hopefully this will help your next Jenkins build setup go much easier!