Something went wrong. Try again.
Web frontend and supporting services for lance.blue
Something went wrong. Try again.
4.4 kB · 117 lines
Shell
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118#!/usr/bin/env bash# Push both artifacts and point infra at them.## scripts/deploy.sh## Runs the api build and push, then the site build and push, then writes the# release id both were named after into infra's releases.auto.tfvars.json.# The result is one uncommitted infra diff; applying it is the deploy, and# this script does not apply anything.## INFRA_DIR overrides where the infra checkout is; the default is the sibling# directory, which is how the repos are laid out.set -euo pipefail
cd "$(dirname "$0")/.."
# Everything below fails before anything is built. A half-finished deploy is# recoverable - the artifacts are named after the commit and nothing serves# them until the apply - but a wasted build is still a wasted five minutes.
: "${AWS_PROFILE:?set AWS_PROFILE; default credentials are almost never the right account}"
# The variable being set says nothing about the session behind it. Ask STS# now, so an expired login fails here instead of after both builds, when the# api push is the first thing to touch AWS.if ! aws sts get-caller-identity --query Account --output text >/dev/null; then echo "deploy: no working AWS session for profile $AWS_PROFILE; log in again" >&2 exit 1fi
command -v jq >/dev/null || { echo "deploy: jq is not installed; it writes releases.auto.tfvars.json" >&2 exit 1}
if ! infra="$(cd "${INFRA_DIR:-../infra}" 2>/dev/null && pwd)"; then echo "deploy: no infra checkout at ${INFRA_DIR:-../infra}; set INFRA_DIR" >&2 exit 1fitfvars="$infra/envs/lance.blue/releases.auto.tfvars.json"
[ -f "$tfvars" ] || { echo "deploy: $infra has no envs/lance.blue/releases.auto.tfvars.json" >&2 exit 1}
# A dirty tree gets a -dirty ref, which names a build nobody else can rebuild.if [ -n "$(git status --porcelain)" ]; then echo "deploy: headquarters has uncommitted changes; commit or stash them" >&2 exit 1fi
# Deploying off a branch is fine: the branch name is part of the release id, so# what is serving is legible from the id alone. main is the one branch with a# rule, because a main build is meant to be exactly what the remote has. Ask# the remote rather than trusting whatever the last fetch left behind.branch=$(git rev-parse --abbrev-ref HEAD)if [ "$branch" = main ]; then git fetch --quiet origin main if [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/main)" ]; then echo "deploy: on main, but HEAD is not origin/main; pull or push first" >&2 exit 1 fifi
# Nothing here cares whether infra is dirty. headquarters and arena each write# their own keys in the same file, so the second one to deploy would always# find the first one's bump sitting there uncommitted. infra's own deploy.sh is# where a clean tree is required.
BUILD_REF="$(scripts/build-ref.sh)"export BUILD_REF
echo "deploy: $BUILD_REF -> $AWS_PROFILE"echo
# The push scripts build again from cache, so this is mostly a fail-fast: a# broken build stops here rather than after the api image is in ECR.services/api/build.shweb/scripts/build.sh
# What the tfvars file gets is read back out of the pushes rather than assumed,# so a change to how either one names a build fails here instead of pointing# production at a path that does not exist.logs="$(mktemp -d)"trap 'rm -rf "$logs" "$tfvars.new"' EXIT
services/api/push.sh 2>&1 | tee "$logs/api"web/scripts/push.sh 2>&1 | tee "$logs/web"
# "Pushed <registry>/headquarters-api:<ref>"image="$(grep -E '^Pushed [^ ]+:' "$logs/api" | tail -n 1 || true)"api_ref="${image##*:}"# "Pushed to s3://<bucket>/releases/<ref>"prefix="$(grep -E '^Pushed to s3://' "$logs/web" | tail -n 1 || true)"site_ref="${prefix##*/}"
for ref in "$api_ref" "$site_ref"; do if [ "$ref" != "$BUILD_REF" ]; then echo >&2 echo "deploy: pushed $api_ref and $site_ref, expected $BUILD_REF" >&2 echo "deploy: $tfvars not touched" >&2 exit 1 fidone
# Written beside the file it replaces so the move is atomic; a jq that fails# halfway leaves the current release id in place.jq --arg ref "$BUILD_REF" '.releases.api = $ref | .releases.site = $ref' \ "$tfvars" >"$tfvars.new"mv "$tfvars.new" "$tfvars"
echoecho "Wrote releases.api and releases.site = $BUILD_REF"echo "To serve it:"echo " tofu -chdir=$infra/envs/lance.blue plan -out=lance.blue.tfplan"echo " tofu -chdir=$infra/envs/lance.blue apply lance.blue.tfplan"