#!/bin/bash ######################################################################################## # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 ######################################################################################## source ./common.sh # # @function usage # function usage() { echo -e " ------------------------------------------------------------------------------ This script should be run from the repo's deployment directory ------------------------------------------------------------------------------ cd deployment bash ./build-s3-dist.sh --bucket BUCKET_NAME where --bucket BUCKET_NAME specify the bucket name where the templates and packages deployed to. " return 0 } ###################################################################### # # BUCKET must be defined through commandline option # # --bucket BUCKET_NAME # BUILD_ENV= while [[ $# -gt 0 ]]; do key="$1" case $key in -b|--bucket) BUCKET="$2" shift # past key shift # past value ;; -s|--solution) SOLUTION="$2" shift # past key shift # past value ;; -v|--version) VERSION="$2" shift # past key shift # past value ;; -d|--dev) BUILD_ENV="dev" shift # past key ;; -r|--single-region) SINGLE_REGION=true shift # past key ;; *) shift ;; esac done ## configure global variables NODEJS_VERSION=$(node --version) DEPLOY_DIR="$PWD" SOURCE_DIR="$DEPLOY_DIR/../source" TEMPLATE_DIST_DIR="$DEPLOY_DIR/global-s3-assets" BUILD_DIST_DIR="$DEPLOY_DIR/regional-s3-assets" TMP_DIR=$(mktemp -d) [ -z "$BUCKET" ] && \ echo "error: missing --bucket parameter..." && \ usage && \ exit 1 [ -z "$VERSION" ] && \ VERSION=$(cat "$SOURCE_DIR/.version") [ -z "$VERSION" ] && \ echo "error: can't find the versioning, please use --version parameter..." && \ usage && \ exit 1 [ -z "$SOLUTION" ] && \ SOLUTION="shot-detection-demo" [ -z "$SINGLE_REGION" ] && \ SINGLE_REGION=true ## Lambda layer package(s) LAYER_AWSSDK= LAYER_CORE_LIB= LAYER_MEDIAINFO= # note: core-lib for custom resource LOCAL_PKG_CORE_LIB= ## modular workflow package(s) PKG_CUSTOM_RESOURCES= PKG_SHOT_DETECTION= PKG_STATUS_UPDATER= PKG_API= PKG_WEBAPP= ## trap exit signal and make sure to remove the TMP_DIR trap "rm -rf $TMP_DIR" EXIT # # @function clean_start # @description # make sure to have a clean start # function clean_start() { echo "------------------------------------------------------------------------------" echo "Rebuild distribution" echo "------------------------------------------------------------------------------" local dir # remake dirs for dir in "$TEMPLATE_DIST_DIR" "$BUILD_DIST_DIR"; do rm -rf "$dir" runcmd mkdir -p "$dir" done # remove .DS_Store for dir in "$DEPLOY_DIR" "$SOURCE_DIR"; do find "$dir" -name '.DS_Store' -type f -delete done # delete all package-lock.json find "$SOURCE_DIR" -name 'package-lock.json' -type f -delete } function install_dev_dependencies() { echo "------------------------------------------------------------------------------" echo "Install node package dependencies" echo "------------------------------------------------------------------------------" pushd "$SOURCE_DIR" npm install -g \ aws-sdk \ aws-sdk-mock \ chai \ eslint \ eslint-config-airbnb-base \ eslint-plugin-import \ browserify \ terser \ mocha \ nock \ npm-run-all \ sinon \ sinon-chai popd } # # @function build_cloudformation_templates # @description # copy cloudformation templates # replace %PARAMS% variables with real names # function build_cloudformation_templates() { echo "------------------------------------------------------------------------------" echo "CloudFormation Templates" echo "------------------------------------------------------------------------------" # copy yaml to dist folder runcmd cp -rv *.yaml "$TEMPLATE_DIST_DIR/" pushd "$TEMPLATE_DIST_DIR" # solution name echo "Updating %SOLUTION% param in cloudformation templates..." sed -i'.bak' -e "s|%SOLUTION%|${SOLUTION}|g" *.yaml || exit 1 # solution version echo "Updating %VERSION% param in cloudformation templates..." sed -i'.bak' -e "s|%VERSION%|${VERSION}|g" *.yaml || exit 1 # deployment bucket name echo "Updating %BUCKET% param in cloudformation templates..." sed -i'.bak' -e "s|%BUCKET%|${BUCKET}|g" *.yaml || exit 1 # key prefix name local keyprefix="${SOLUTION}/${VERSION}" echo "Updating %KEYPREFIX% param in cloudformation templates..." sed -i'.bak' -e "s|%KEYPREFIX%|${keyprefix}|g" *.yaml || exit 1 # single region flag echo "Updating %SINGLE_REGION% param in cloudformation templates..." sed -i'.bak' -e "s|%SINGLE_REGION%|${SINGLE_REGION}|g" *.yaml || exit 1 # layer(s) echo "Updating %LAYER_AWSSDK% param in cloudformation templates..." sed -i'.bak' -e "s|%LAYER_AWSSDK%|${LAYER_AWSSDK}|g" *.yaml || exit 1 echo "Updating %LAYER_CORE_LIB% param in cloudformation templates..." sed -i'.bak' -e "s|%LAYER_CORE_LIB%|${LAYER_CORE_LIB}|g" *.yaml || exit 1 echo "Updating %LAYER_MEDIAINFO% param in cloudformation templates..." sed -i'.bak' -e "s|%LAYER_MEDIAINFO%|${LAYER_MEDIAINFO}|g" *.yaml || exit 1 # package(s) echo "Updating %PKG_CUSTOM_RESOURCES% param in cloudformation templates..." sed -i'.bak' -e "s|%PKG_CUSTOM_RESOURCES%|${PKG_CUSTOM_RESOURCES}|g" *.yaml || exit 1 echo "Updating %PKG_SHOT_DETECTION% param in cloudformation templates..." sed -i'.bak' -e "s|%PKG_SHOT_DETECTION%|${PKG_SHOT_DETECTION}|g" *.yaml || exit 1 echo "Updating %PKG_STATUS_UPDATER% param in cloudformation templates..." sed -i'.bak' -e "s|%PKG_STATUS_UPDATER%|${PKG_STATUS_UPDATER}|g" *.yaml || exit 1 echo "Updating %PKG_API% param in cloudformation templates..." sed -i'.bak' -e "s|%PKG_API%|${PKG_API}|g" *.yaml || exit 1 echo "Updating %PKG_WEBAPP% param in cloudformation templates..." sed -i'.bak' -e "s|%PKG_WEBAPP%|${PKG_WEBAPP}|g" *.yaml || exit 1 # remove .bak runcmd rm -v *.bak # rename .yaml to .template find . -name "*.yaml" -exec bash -c 'mv -v "$0" "${0%.yaml}.template"' {} \; # copy templates to regional bucket as well cp -v *.template "$BUILD_DIST_DIR" popd } # # @function build_awssdk_layer # @description # build layer packages and copy to deployment/dist folder # function build_awssdk_layer() { echo "------------------------------------------------------------------------------" echo "Building aws-sdk layer package" echo "------------------------------------------------------------------------------" local package="aws-sdk-layer" LAYER_AWSSDK="${SOLUTION}-${package}-${VERSION}.zip" pushd "$SOURCE_DIR/layers/${package}" npm install npm run build npm run zip -- "$LAYER_AWSSDK" . cp -v "./dist/${LAYER_AWSSDK}" "$BUILD_DIST_DIR" popd } # # @function build_core_lib_layer # @description # build layer packages and copy to deployment/dist folder # function build_core_lib_layer() { echo "------------------------------------------------------------------------------" echo "Building Core Library layer package" echo "------------------------------------------------------------------------------" local package="core-lib" LAYER_CORE_LIB="${SOLUTION}-${package}-${VERSION}.zip" pushd "$SOURCE_DIR/layers/${package}" npm install npm run build npm run zip -- "$LAYER_CORE_LIB" . cp -v "./dist/${LAYER_CORE_LIB}" "$BUILD_DIST_DIR" # also create a local package for custom resource pushd "./dist/nodejs/node_modules/${package}" LOCAL_PKG_CORE_LIB="$(pwd)/$(npm pack)" popd popd } function build_mediainfo_layer() { echo "------------------------------------------------------------------------------" echo "Building mediainfo layer package" echo "------------------------------------------------------------------------------" local package="mediainfo" LAYER_MEDIAINFO="${SOLUTION}-${package}-${VERSION}.zip" pushd "$SOURCE_DIR/layers/${package}" npm install npm run build npm run zip -- "$LAYER_MEDIAINFO" . cp -v "./dist/${LAYER_MEDIAINFO}" "$BUILD_DIST_DIR" popd } # # @function build_custom_resources_package # @description # build custom resources package and copy to deployment/dist folder # function build_custom_resources_package() { echo "------------------------------------------------------------------------------" echo "Building custom resources Lambda package" echo "------------------------------------------------------------------------------" local package="custom-resources" PKG_CUSTOM_RESOURCES="${SOLUTION}-${package}-${VERSION}.zip" pushd "$SOURCE_DIR/${package}" npm install npm run build # explicitly package core-lib into custom resource package pushd dist npm install --no-save "$LOCAL_PKG_CORE_LIB" popd # npm run zip -- "$PKG_CUSTOM_RESOURCES" . cp -v "./dist/$PKG_CUSTOM_RESOURCES" "$BUILD_DIST_DIR" popd } # # @function build_api_package # @description # build api lambda package and copy to deployment/dist folder # function build_api_package() { echo "------------------------------------------------------------------------------" echo "Building API Gateway lambda package" echo "------------------------------------------------------------------------------" local package="api" PKG_API="${SOLUTION}-${package}-${VERSION}.zip" pushd "$SOURCE_DIR/${package}" npm install npm run build npm run zip -- "$PKG_API" . cp -v "./dist/$PKG_API" "$BUILD_DIST_DIR" popd } # # @function build_shot_detection_package # @description # build api lambda package and copy to deployment/dist folder # function build_shot_detection_package() { echo "------------------------------------------------------------------------------" echo "Building Step Functions lambda package" echo "------------------------------------------------------------------------------" local package="step" PKG_SHOT_DETECTION="${SOLUTION}-${package}-${VERSION}.zip" pushd "$SOURCE_DIR/${package}" npm install npm run build npm run zip -- "$PKG_SHOT_DETECTION" . cp -v "./dist/$PKG_SHOT_DETECTION" "$BUILD_DIST_DIR" popd } # # @function build_status_updater_package # @description # build status updater package and copy to deployment/dist folder # function build_status_updater_package() { echo "------------------------------------------------------------------------------" echo "Building Status Updater package" echo "------------------------------------------------------------------------------" local package="status-updater" PKG_STATUS_UPDATER="${SOLUTION}-${package}-${VERSION}.zip" pushd "$SOURCE_DIR/${package}" npm install npm run build npm run zip -- "$PKG_STATUS_UPDATER" . cp -v "./dist/$PKG_STATUS_UPDATER" "$BUILD_DIST_DIR" popd } # # @function minify_jscript # @description # minify js files # function minify_jscript() { echo "------------------------------------------------------------------------------" echo "Minify Webapp code" echo "------------------------------------------------------------------------------" local file=$1 pushd "$SOURCE_DIR/build" npm install --production node post-build.js minify --dir "$file" [ $? -ne 0 ] && exit 1 popd } # # @function compute_jscript_integrity # @description # compute and inject SRI to index.html # function compute_jscript_integrity() { echo "------------------------------------------------------------------------------" echo "Compute and Inject Integrity check to webapp" echo "------------------------------------------------------------------------------" local file=$1 pushd "$SOURCE_DIR/build" npm install --production node post-build.js inject-sri --html "$file" [ $? -ne 0 ] && exit 1 popd } function build_thirdparty_bundle() { echo "------------------------------------------------------------------------------" echo "Building $1" echo "------------------------------------------------------------------------------" local bundle=$1 local bundle_dir="$SOURCE_DIR/webapp/third_party/$bundle" pushd "$bundle_dir" npm install --production npm run build [ $? -ne 0 ] && exit 1 popd } function build_webapp_dependencies() { echo "------------------------------------------------------------------------------" echo "Building webapp dependenceis for browser" echo "------------------------------------------------------------------------------" local bundles=(\ "aws-sdk-bundle" \ "amazon-cognito-identity-bundle" \ "videojs-bundle" \ "videojs-markers-bundle" \ "bootstrap-bundle" \ "fontawesome-bundle" \ "jquery-bundle" \ "popper-bundle" \ "crypto-js-bundle" \ ) for bundle in ${bundles[@]} do build_thirdparty_bundle $bundle done; # copy all dependencies to webapp/third_party/dist local srcdir="$SOURCE_DIR/webapp/third_party" local dstdir="$SOURCE_DIR/webapp/third_party/dist" rm -rf "$dstdir" && mkdir -p "$dstdir" cp -rv "$srcdir"/*/dist/js "$dstdir" cp -rv "$srcdir"/*/dist/css "$dstdir" cp -rv "$srcdir"/*/dist/webfonts "$dstdir" } # # @function build_webapp_package # @description # build webapp package and copy to deployment/dist folder # function build_webapp_package() { echo "------------------------------------------------------------------------------" echo "Building webapp package" echo "------------------------------------------------------------------------------" local package="webapp" PKG_WEBAPP="${SOLUTION}-${package}-${VERSION}.zip" pushd "$SOURCE_DIR/${package}" npm install npm run build # start building all third party bundles build_webapp_dependencies # copy all dependencies to webapp/dist/third_party local srcdir="$SOURCE_DIR/${package}/third_party/dist" local dstdir="$SOURCE_DIR/${package}/dist/third_party/dist" mkdir -p "$dstdir" cp -rv "$srcdir/" "$dstdir" minify_jscript "$SOURCE_DIR/${package}/dist/src/lib/js" compute_jscript_integrity "$SOURCE_DIR/${package}/dist/index.html" # now, zip and package all the files npm run zip -- "$PKG_WEBAPP" . -x ./dev** cp -v "./dist/$PKG_WEBAPP" "$BUILD_DIST_DIR" popd } function on_complete() { echo "------------------------------------------------------------------------------" echo "S3 Packaging Complete. (${SOLUTION} ${VERSION})" echo "------------------------------------------------------------------------------" echo "** LAYER_AWSSDK=${LAYER_AWSSDK} **" echo "** LAYER_MEDIAINFO=${LAYER_MEDIAINFO} **" echo "** LAYER_CORE_LIB=${LAYER_CORE_LIB} **" echo "** PKG_CUSTOM_RESOURCES=${PKG_CUSTOM_RESOURCES} **" echo "** PKG_SHOT_DETECTION=${PKG_SHOT_DETECTION} **" echo "** PKG_STATUS_UPDATER=${PKG_STATUS_UPDATER} **" echo "** PKG_API=${PKG_API} **" echo "** PKG_WEBAPP=${PKG_WEBAPP} **" } clean_start install_dev_dependencies build_awssdk_layer build_core_lib_layer build_mediainfo_layer build_custom_resources_package build_api_package build_shot_detection_package build_status_updater_package build_webapp_package build_cloudformation_templates on_complete