teleport/build.assets/build-webassets-if-changed.sh
Cam Hutchison 886cd70fb6
web: Ignore .swc directory when computing web SHA (#29892)
Ignore any `.swc` directories when computing the SHA of SHAs to
determine if `make ensure-webassets` should rebuild the web UI. The
`.swc` directories are in the `.gitignore` file, so should also be
ignored when computing the SHA of the web files.

On a fresh checkout of `teleport`, running `make ensure-webassets`
causes a plugin to be build or downloaded into
`web/packages/teleport/.swc/plugins/v4`. As this is inside the directory
over which the SHA of SHAs is computed, if you re-run
`make ensure-webassets`, it ends up rebuilding the web UI for the same
result. It should not rebuild the web UI if it hasn't changed. The SHA
of SHAs generated from a fresh checkout of teleport should match another
fresh checkout. This fails as generating the enterprise webassets after
generating the OSS webassets includes the plugin as part of the SHA, and
that is not there on a fresh checkin.

This will make a difference if we want to build the web assets as a
separate step on CI so that the `webassets` directory can be copied into
other builds. This will allow a later version of node.js to be used to
build the web UI that what may be available on the OS we're building
Teleport on (I'm looking at you, Centos 7).

Fix a shellcheck-reported issue of quoting while we're here.
2023-08-02 09:59:55 +00:00

91 lines
2.5 KiB
Bash
Executable file

#!/bin/bash
#
# Rebuilds a UI make target based on whether the given directories contents have changed
# minus any node-modules.
#
set -eo pipefail
ROOT_PATH="$(cd "$(dirname "$0")/.." && pwd -P)"
MAKE="${MAKE:-make}"
SHASUMS=("shasum -a 512" "sha512sum")
if ! command -v "$MAKE" >/dev/null; then
echo "Unable to find \"$MAKE\" on path."
exit 1
fi
if [ -n "$SHASUM" ]; then
EXEC="$(echo "$SHASUM" | awk '{print $1}')"
if ! command -v "$EXEC" >/dev/null; then
echo "Unable to find custom SHA sum $SHASUM on path."
exit 1
fi
else
for shasum in "${SHASUMS[@]}"; do
EXEC="$(echo "$shasum" | awk '{print $1}')"
if command -v "$EXEC" >/dev/null; then
SHASUM="$shasum"
break
fi
done
fi
if [ -z "$SHASUM" ]; then
echo "Unable to find a SHA sum executable."
exit 1
fi
if [ "$#" -lt 4 ]; then
echo "Usage: $0 <type> <last-sha-file> <build-target> <directories...>"
exit 1
fi
TYPE="$1"
LAST_SHA_FILE="$ROOT_PATH/$2"
BUILD_TARGET="$3"
shift 3
SRC_DIRECTORIES=("$@")
for i in "${!SRC_DIRECTORIES[@]}"; do
SRC_DIRECTORIES[i]="$ROOT_PATH/${SRC_DIRECTORIES[i]}"
done
function calculate_sha() {
#shellcheck disable=SC2086
#We want to split $SHASUM on spaces so we dont want it quoted.
find "${SRC_DIRECTORIES[@]}" "$ROOT_PATH/package.json" "$ROOT_PATH/yarn.lock" \
-not \( -type d \( -name node_modules -o -name .swc \) -prune \) \
-type f -print0 | \
LC_ALL=C sort -z | xargs -0 $SHASUM | awk '{print $1}' | $SHASUM | tr -d ' -'
}
# Calculate the current hash-of-hashes of the given source directories. Adds in package.json as well.
# This excludes node_modules, as the package.json differences should handle this.
CURRENT_SHA="$(calculate_sha)"
BUILD=true
# If the LAST_SHA_FILE exists, test whether it's equivalent to the current calculated SHA. If it is,
# set BUILD to false.
if [ -f "$LAST_SHA_FILE" ]; then
LAST_SHA="$(cat "$LAST_SHA_FILE")"
if [ "$LAST_SHA" = "$CURRENT_SHA" ]; then
BUILD=false
fi
fi
# If BUILD is true, make the build target. This assumes using the root Makefile.
if [ "$BUILD" = "true" ]; then \
"$MAKE" -C "$ROOT_PATH" "$BUILD_TARGET"; \
# Recalculate the current SHA and record into the LAST_SHA_FILE. The make target is expected to have
# created any necessary directories here. The recalculation is necessary as yarn.lock may have been
# updated by the build process.
mkdir -p "$(dirname "$LAST_SHA_FILE")"
# Save SHA with yarn.lock before yarn install
echo "$CURRENT_SHA" > "$LAST_SHA_FILE"
echo "$TYPE webassets successfully updated."
else
echo "$TYPE webassets up to date."
fi