89 lines
2.3 KiB
Bash
Executable File
89 lines
2.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
umask 077
|
|
|
|
ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
|
|
action=${1:-plan}
|
|
ssh_target=${2:-whoneedhelp}
|
|
|
|
case "$action" in
|
|
plan | prepare | apply) ;;
|
|
*)
|
|
echo "Usage: $0 [plan|prepare|apply] [SSH_TARGET]" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
for command in git mktemp realpath; do
|
|
command -v "$command" >/dev/null 2>&1 || {
|
|
echo "Required command is unavailable: $command" >&2
|
|
exit 2
|
|
}
|
|
done
|
|
|
|
candidate=$(git -C "$ROOT" rev-parse --verify HEAD)
|
|
artifact_root=${WNH_PRODUCTION_RELEASE_ARTIFACT_ROOT:-"$ROOT/output/releases"}
|
|
case "$artifact_root" in
|
|
/*) ;;
|
|
*)
|
|
echo "WNH_PRODUCTION_RELEASE_ARTIFACT_ROOT must be an absolute path." >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
mkdir -p "$artifact_root"
|
|
artifact_root=$(realpath --canonicalize-existing "$artifact_root")
|
|
|
|
worktree_root=${WNH_PRODUCTION_RELEASE_WORKTREE_ROOT:-"$ROOT/output/release-worktrees"}
|
|
case "$worktree_root" in
|
|
/*) ;;
|
|
*)
|
|
echo "WNH_PRODUCTION_RELEASE_WORKTREE_ROOT must be an absolute path." >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
mkdir -p "$worktree_root"
|
|
worktree_root=$(realpath --canonicalize-existing "$worktree_root")
|
|
chmod 700 "$worktree_root"
|
|
|
|
checkout=$(mktemp -d "$worktree_root/${candidate}.XXXXXX")
|
|
rmdir "$checkout"
|
|
worktree_added=false
|
|
|
|
cleanup() {
|
|
local status=$?
|
|
trap - EXIT HUP INT TERM
|
|
if [[ "$worktree_added" == true ]]; then
|
|
git -C "$ROOT" worktree remove --force "$checkout" >/dev/null 2>&1 || true
|
|
fi
|
|
if [[ -d "$checkout" ]]; then
|
|
rmdir "$checkout" >/dev/null 2>&1 || true
|
|
fi
|
|
exit "$status"
|
|
}
|
|
trap cleanup EXIT
|
|
trap 'exit 129' HUP
|
|
trap 'exit 130' INT
|
|
trap 'exit 143' TERM
|
|
|
|
worktree_added=true
|
|
git -C "$ROOT" worktree add --quiet --detach "$checkout" "$candidate"
|
|
|
|
[[ -z "$(git -C "$checkout" status --porcelain --untracked-files=no)" ]] || {
|
|
echo "The detached release checkout is unexpectedly dirty." >&2
|
|
exit 2
|
|
}
|
|
[[ "$(git -C "$checkout" rev-parse --verify HEAD)" == "$candidate" ]] || {
|
|
echo "The detached release checkout does not match the selected commit." >&2
|
|
exit 2
|
|
}
|
|
|
|
printf 'Release candidate: %s\n' "$candidate"
|
|
printf 'Clean detached checkout: %s\n' "$checkout"
|
|
printf 'Artifact root: %s\n' "$artifact_root"
|
|
|
|
(
|
|
cd "$checkout"
|
|
WNH_PRODUCTION_RELEASE_ARTIFACT_ROOT="$artifact_root" \
|
|
./scripts/production-release.sh "$action" "$ssh_target"
|
|
)
|