Created
April 27, 2023 13:23
-
-
Save chadwcarlson/15cb3cff7243cccf67fd69bb1345747a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# pbt - Platform.sh Build Tools | |
# 1) build cache handling | |
# 2) common framework recipes | |
# | |
# What also could change? | |
# - any variable defined in variables in .platform.app.yaml | |
# - Using a specific variables.pbt for cache handling config | |
# - A forced rebuild environment variable (to catch other cases) | |
# - composability: resusing the caching logic for dirs and build deps --> cached-poetry; cached-pip | |
# - yq: installing and caching yq so as to make parsing CACHE_DIRS and other array vars simpler. | |
####################################################################################################################### | |
# User/app-specific configuration. | |
# Directories to hold in build cache. | |
CACHED_DIRS=( ".global" ".local" ".venv" ) | |
# The primary build steps. | |
build() { | |
# Upgrade pip. | |
./cached_pip.sh | |
# Install poetry. | |
./cached_poetry.sh | |
} | |
####################################################################################################################### | |
# Script config, defaults, and helper functions. | |
# Track build time. | |
SECONDS=0 | |
REBUILD=0 | |
# Internal build cache tracking files. | |
CACHED_LOCKFILE_NAME="$PLATFORM_CACHE_DIR/platform_cache.deps" | |
CACHED_VARIABLES_FILE_NAME="$PLATFORM_CACHE_DIR/platform_cache.vars" | |
BUILD_TIME_FILE_NAME="$PLATFORM_CACHE_DIR/platform_cache.time" | |
# Helper function to handle cached directories. | |
apply_to_all_dirs() { | |
CMD=$1 | |
for cache_dir in "${CACHED_DIRS[@]}" | |
do | |
eval $CMD | |
done | |
} | |
# Helper function for human readable build time output. | |
# Modified from https://stackoverflow.com/a/56530876. | |
secs_to_human() { | |
if [[ -z ${1} || ${1} -lt 60 ]] ;then | |
min=0 ; secs="${1}" | |
else | |
time_mins=$(echo "scale=2; ${1}/60" | bc) | |
min=$(echo ${time_mins} | cut -d'.' -f1) | |
secs="0.$(echo ${time_mins} | cut -d'.' -f2)" | |
secs=$(echo ${secs}*60|bc|awk '{print int($1+0.5)}') | |
fi | |
echo "${min}m${secs}s" | |
} | |
# Helper function for tracking cached build time. | |
track_build_time () { | |
COMPLETE_TIME=$(secs_to_human $SECONDS) | |
if [ -f "$BUILD_TIME_FILE_NAME" ]; then | |
LAST_FULL_BUILD_TIME=$(cat $BUILD_TIME_FILE_NAME) | |
if [ "$REBUILD" -eq "0" ]; then | |
printf "\nCached build time: $COMPLETE_TIME" | |
else | |
printf "\nCurrent build time: $COMPLETE_TIME" | |
fi | |
printf "\nLast full build time: $LAST_FULL_BUILD_TIME" | |
echo $COMPLETE_TIME > $BUILD_TIME_FILE_NAME | |
else | |
echo $COMPLETE_TIME > $BUILD_TIME_FILE_NAME | |
printf "\nCurrent build time: $COMPLETE_TIME" | |
fi | |
} | |
cached_build() { | |
# rm -rf $PLATFORM_CACHE_DIR/* | |
# Check that we're in a build phase on Platform.sh first. | |
if [[ -v PLATFORM_CACHE_DIR ]]; then | |
printf "\nPlatform.sh build cache handling.\n" | |
# Compare current dependencies to cached versions. | |
if [ -f "$CACHED_LOCKFILE_NAME" ] && [ -f "$CACHED_VARIABLES_FILE_NAME" ]; then | |
printf "\nBuild cache found." | |
# Restore current cache to $HOME. | |
printf "\nTemporarily restoring from build cache.\n" | |
apply_to_all_dirs 'rsync -ar $PLATFORM_CACHE_DIR/$cache_dir/ $HOME/$cache_dir' | |
# Compare build cache versions. | |
# a. From dependencies | |
export PATH="$HOME/.local/bin:$PATH" | |
CURRENT_VERSION=$(poetry export | base64) | |
CACHED_LOCKFILE=$(cat $CACHED_LOCKFILE_NAME) | |
# b. From .platform.app.yaml defined variables. | |
CURRENT_VARS=$(echo $PLATFORM_APPLICATION | base64 --decode | jq -r '.variables' | base64) | |
CACHED_VARS=$(cat $CACHED_VARIABLES_FILE_NAME) | |
echo $CURRENT_VARS | |
echo $CACHED_VARS | |
if [ "$CACHED_LOCKFILE" != "$CURRENT_VERSION" ] || [ "$CACHED_VARS" != "$CURRENT_VARS" ]; then | |
printf "\nThe environment has changed and must be rebuilt.\n" | |
printf "\nClearing build cache.\n" | |
# 1. Remove cached dirs. | |
printf "\nRemoving cached dirs" | |
apply_to_all_dirs 'rm -rf $HOME/$cache_dir' | |
# 2. Run build. | |
printf "\nRunning build" | |
build | |
# 3. Track rebuild. | |
printf "\nTracking build" | |
export REBUILD=1 | |
# 4. Cache dirs. | |
printf "\nCaching dirs" | |
apply_to_all_dirs 'rsync -ar $HOME/$cache_dir/ $PLATFORM_CACHE_DIR/$cache_dir' | |
# 5. Generate cache lock file. | |
printf "\nGenerating new cache lock file" | |
poetry export | base64 > $CACHED_LOCKFILE_NAME | |
else | |
printf "\nNo changes to environment found. Using restored build cache.\n" | |
fi | |
else | |
printf "\nBuild cache lockfiles do not exist." | |
# 1. Run build. | |
printf "\nRunning build" | |
build | |
# 2. Track rebuild. | |
printf "\nTracking rebuild" | |
export REBUILD=1 | |
# 3. Cache dirs. | |
printf "\nCaching dirs" | |
apply_to_all_dirs 'rsync -ar $HOME/$cache_dir/ $PLATFORM_CACHE_DIR/$cache_dir' | |
# 4. Generate cache lock file. | |
printf "\nGenerating cache lock files" | |
# a. For dependencies. | |
export PATH="$HOME/.local/bin:$PATH" | |
poetry export | base64 > $CACHED_LOCKFILE_NAME | |
# b. For .platform.app.yaml defined variables. | |
echo $PLATFORM_APPLICATION | base64 --decode | jq -r '.variables' | base64 > $CACHED_VARIABLES_FILE_NAME | |
fi | |
else | |
printf "\nNot in a Platform.sh build phase. Skipping.\n" | |
fi | |
track_build_time $SECONDS | |
} | |
# Build the app if cache differs or does not exist yet. | |
cached_build |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
cached_pip
cached_poetry.sh