Something went wrong. Try again.
Identities for entities did.bot
agent llm did
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139#!/usr/bin/env bash# Builds didbot-pds for linux/amd64 from a commit's tree and pushes it to# infra/pds's own ECR repository, tagged by that commit's short sha and,# optionally, by a second tag -- a release name, most often.## scripts/publish-image.sh # HEAD, tagged by its short sha# scripts/publish-image.sh <rev> # any commit-ish# scripts/publish-image.sh <rev> <release-tag> # also tagged <release-tag>## infra/pds/variables.tf's container_image_tag is the tag to apply that# stack with once a push has landed -- this prints it at the end.## There is no CI job that does this: the runner .tangled/workflows/ci.yml# describes holds no AWS credential and has no safe way to hold one, so# publishing an image is an operator's own command, run with their own# credentials, same as scripts/publish-site.sh and scripts/release.sh# elsewhere in this project are.## Credentials are the caller's own -- the environment or a profile: this# script does not assume which, only that `aws sts get-caller-identity`# answers.set -euo pipefail
cd "$(dirname "$0")/.."
stack=infra/pds
usage() { echo "usage: scripts/publish-image.sh [<rev>] [<release-tag>]" >&2}
rev=""release_tag=""for arg in "$@"; do case "$arg" in -h | --help) usage exit 0 ;; -*) usage exit 2 ;; *) if [ -z "$rev" ]; then rev="$arg" elif [ -z "$release_tag" ]; then release_tag="$arg" else usage exit 2 fi ;; esacdonerev="${rev:-HEAD}"
say() { printf '\033[1m==> %s\033[0m\n' "$*" >&2; }
for tool in docker git aws tofu; do command -v "$tool" >/dev/null || { echo "publish-image: $tool is required and was not found on PATH" >&2 exit 1 }done
# The release is the commit, so an image can be traced back to what built# it. `git archive` below is what keeps a dirty working tree out of it: only# what this sha actually holds is sent to the builder.sha="$(git rev-parse --verify --quiet --short=12 "$rev^{commit}")" || { echo "publish-image: $rev is not a commit" >&2 exit 1}
for path in Dockerfile Cargo.toml Cargo.lock; do git cat-file -e "$sha:$path" 2>/dev/null || { echo "publish-image: $path is not in $sha; only a commit carrying it can be published" >&2 exit 1 }done
identity="$(aws sts get-caller-identity --output text --query Arn 2>&1)" || { echo "publish-image: AWS credential check failed:" >&2 echo " ${identity}" >&2 echo "publish-image: log in to the account this stack deploys to, then re-run." >&2 exit 1}say "publishing as ${identity}"
repository_url="$(tofu -chdir="$stack" output -raw ecr_repository_url 2>/dev/null)" || { echo "publish-image: no ecr_repository_url output from $stack." >&2 echo "publish-image: run \`tofu -chdir=$stack apply -target=aws_ecr_repository.pds\` first --" >&2 echo "publish-image: see docs/deployment.md's \"Bring-up\"." >&2 exit 1}# repository_url is <account>.dkr.ecr.<region>.amazonaws.com/<repo>; the# region is the fourth dot-separated field of the registry host.region="$(cut -d. -f4 <<<"${repository_url%%/*}")"
aws ecr get-login-password --region "$region" \ | docker login --username AWS --password-stdin "${repository_url%%/*}" >/dev/null
already_pushed() { aws ecr describe-images --region "$region" \ --repository-name "${repository_url#*/}" --image-ids "imageTag=$1" >/dev/null 2>&1}
if already_pushed "$sha"; then say "${repository_url}:${sha} is already in the registry"else work="$(mktemp -d -t didbot-publish-image-XXXXXX)" trap 'rm -rf "$work"' EXIT git archive "$sha" | tar -x -C "$work"
tags=(--tag "${repository_url}:${sha}") [ -n "$release_tag" ] && tags+=(--tag "${repository_url}:${release_tag}")
say "building and pushing ${repository_url}:${sha} for linux/amd64" docker buildx build \ --platform linux/amd64 \ "${tags[@]}" \ --push \ "$work"fi
if [ -n "$release_tag" ] && ! already_pushed "$release_tag"; then # The sha build above already pushed this tag when both were built # together; this only fires when the sha was already in the registry and # the release tag is new -- retagging an existing manifest rather than # rebuilding it. say "tagging existing ${repository_url}:${sha} as ${release_tag}" docker buildx imagetools create \ --tag "${repository_url}:${release_tag}" \ "${repository_url}:${sha}"fi
say "published. Apply with:"echo " tofu -chdir=${stack} apply -var container_image_tag=${release_tag:-$sha}"