#!/usr/bin/env bash set -eu cd "$(dirname "$0")" # # Constants and defaults # DOCKER_REPO=fpco/stack-build PUSH=false DRY=false VARIANT=build # # Functions # # Print usage information and exit with failure status. First argument is an # error message. usage() { echo "$0: $1" >&2 echo echo "Usage: $0 [--push] [--dry-run] [--small] lts-X.Y]" echo "See README.md for more information." echo exit 1 } # Print a command, and if --dry-run disabled also run it dry() { echo ">>> $*" [[ $DRY = true ]] || "$@" } # Push an image if --push is enabled (otherwise do nothing) push() { [[ $PUSH = false ]] || dry docker push "$1" } # Tag an image, and then push it if --push is enabled tagpush() { dry docker tag "$1" "$2" push "$2" } # # Parse command-line # LTS_SLUG_ARG= while [[ $# -gt 0 ]]; do case "$1" in --push) PUSH=true shift ;; --dry-run) DRY=true shift ;; --small) VARIANT=small DOCKER_REPO=fpco/stack-build-small shift ;; -*) usage "Unknown option: $1" ;; *) if [[ -n "$LTS_SLUG_ARG" ]]; then usage "Cannot specify multiple snapshots: $1" fi LTS_SLUG_ARG="$1" shift ;; esac done case "$LTS_SLUG_ARG" in "") usage "Missing argument: snapshot" ;; lts-*.*) LTS_SLUG="$LTS_SLUG_ARG" ;; *) echo "$0: Wrong snapshot format: $LTS_SLUG_ARG" >&2 exit 1 ;; esac # # Determine if lts slug is latest # SNAPSHOTS="$(mktemp "lts-snapshots.json.XXXXXX")" trap "rm -f \"$SNAPSHOTS\"" EXIT wget -qO- https://www.stackage.org/download/lts-snapshots.json >"$SNAPSHOTS" LTS_VERSION="${LTS_SLUG#lts-}" LTS_MAJOR="${LTS_VERSION%.*}" LTS_MINOR="${LTS_VERSION#*.}" # # Determine latest LTS version # if [[ ! -x "$HOME/.local/bin/jq" ]]; then mkdir -p $HOME/.local/bin if [[ "$(uname)" = "Darwin" ]]; then curl -o $HOME/.local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-osx-amd64 else curl -o $HOME/.local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64 fi chmod +x $HOME/.local/bin/jq fi LATEST_LTS_SLUG=$($HOME/.local/bin/jq -r ".[\"lts\"]" $SNAPSHOTS) LATEST_LTS_VERSION="${LATEST_LTS_SLUG#lts-}" LATEST_LTS_MAJOR="${LATEST_LTS_VERSION%.*}" LATEST_LTS_MINOR="${LATEST_LTS_VERSION#*.}" # # Determine latest minor version of the selected major version # MAJOR_LATEST_LTS_SLUG=$(jq -r ".[\"lts-$LTS_MAJOR\"]" $SNAPSHOTS) MAJOR_LATEST_LTS_VERSION="${MAJOR_LATEST_LTS_SLUG#lts-}" MAJOR_LATEST_LTS_MAJOR="${MAJOR_LATEST_LTS_VERSION%.*}" MAJOR_LATEST_LTS_MINOR="${MAJOR_LATEST_LTS_VERSION#*.}" # # Find the Dockerfile for the selected snapshot # if [[ -s "$LTS_SLUG/Dockerfile" ]]; then # If there is an exact match, build and push that image sed "s/\\\$DOCKER_REPO/$(echo $DOCKER_REPO|sed 's/\//\\\//')/g" "$LTS_SLUG/Dockerfile" >"$LTS_SLUG/Dockerfile.sub" dry docker build -t "$DOCKER_REPO:$LTS_SLUG" --build-arg "DOCKER_REPO=$DOCKER_REPO" --build-arg "LTS_SLUG=$LTS_SLUG" --build-arg "VARIANT=$VARIANT" -f "$LTS_SLUG/Dockerfile.sub" "$LTS_SLUG" rm -f "$LTS_SLUG/Dockerfile.sub" push "$DOCKER_REPO:$LTS_SLUG" else # If no exact match, find a dockerfile for any earlier minor version of the # selected major version, and just create a new tag from version's image with the selected # minor version (assuming that nothing needs to change), and push it. minor=$(( LTS_MINOR - 1 )) while [[ ! -s "lts-$LTS_MAJOR.$minor/Dockerfile" && $minor -ge 0 ]]; do minor=$(( minor - 1 )) done if [[ $minor -lt 0 ]]; then echo "$0: Cannot find any Dockerfile for LTS major version" >&2 exit 1 fi dry docker pull "$DOCKER_REPO:lts-$LTS_MAJOR.$minor" || true tagpush "$DOCKER_REPO:lts-$LTS_MAJOR.$minor" "$DOCKER_REPO:$LTS_SLUG" fi # # Create and push additional tags # # If we select the latest minor version for the selected major version, then # also create and push an 'lts-X' tag. if [[ $LTS_MINOR -ge $MAJOR_LATEST_LTS_MINOR ]]; then tagpush "$DOCKER_REPO:$LTS_SLUG" "$DOCKER_REPO:lts-$LTS_MAJOR" fi # If we selected the latest LTS snapshot, also create and push the 'lts' and 'latest' tags. if [[ "$LTS_MAJOR" = "$LATEST_LTS_MAJOR" ]] && [[ $LTS_MINOR -ge $LATEST_LTS_MINOR ]]; then tagpush "$DOCKER_REPO:$LTS_SLUG" "$DOCKER_REPO:lts" tagpush "$DOCKER_REPO:$LTS_SLUG" "$DOCKER_REPO:latest" fi