scripts/undo-release.sh
Rama main · réplica de lectura del repositorio original.
#!/usr/bin/env bash
set -euo pipefail
OPTION="$*"
VERSION_FILE=release.json
CHANGE_DIRECTORY=.changes
BOLD=$'\033[1m' BLUE=$'\033[34m' GREEN=$'\033[32m' RED=$'\033[31m' DIM=$'\033[2m' RESET=$'\033[0m'
heading() { printf '\n %s%s%s\n' "$BOLD" "$*" "$RESET"; }
info() { printf ' %sℹ%s %s\n' "$BLUE" "$RESET" "$*"; }
ok() { printf ' %s✔%s %s\n' "$GREEN" "$RESET" "$*"; }
die() {
printf ' %s✖%s %s\n' "$RED" "$RESET" "$*" >&2
exit 1
}
confirm() {
local answer
printf '\n %s [y/N] ' "$*"
read -r answer
[[ "$answer" =~ ^[Yy]$ ]]
}
cd "$(dirname "$0")/.."
main() {
[ -z "$OPTION" ] || die "'$OPTION' is not an option, expected none"
check_repository
heading "Undoing $(git log -1 --format='%h %s')"
info "resets the commit and restores $VERSION_FILE, CHANGELOG.md and $CHANGE_DIRECTORY"
confirm "Continue?" || die "aborted, nothing changed"
undo_commit
}
check_repository() {
local branch
git rev-parse --is-inside-work-tree > /dev/null 2>&1 || die "$PWD is not a git repository"
branch="$(git rev-parse --abbrev-ref HEAD)"
git diff --quiet HEAD~1 HEAD -- . ":(exclude)$VERSION_FILE" ":(exclude)CHANGELOG.md" ":(exclude)$CHANGE_DIRECTORY" || die "the last commit changes more than $VERSION_FILE, CHANGELOG.md and $CHANGE_DIRECTORY, expected a release commit"
[ "$(versions_at HEAD~1)" != "$(versions_at HEAD)" ] || die "the last commit keeps the versions in $VERSION_FILE at $(versions_at HEAD), expected a release commit"
[ -z "$(git status --porcelain -- "$VERSION_FILE" CHANGELOG.md "$CHANGE_DIRECTORY")" ] || die "$VERSION_FILE, CHANGELOG.md or $CHANGE_DIRECTORY has uncommitted changes, commit or stash them first"
git fetch --quiet origin || die "could not fetch origin"
[ "$(git rev-list --count "origin/$branch..HEAD")" -ge 1 ] || die "the release commit is on origin/$branch already, nothing to undo locally"
}
undo_commit() {
git reset --quiet --soft HEAD~1
git restore --staged --worktree "$VERSION_FILE" CHANGELOG.md "$CHANGE_DIRECTORY"
ok "reset to $DIM$(git rev-parse --short HEAD)$RESET $(git log -1 --format=%s)"
ok "$VERSION_FILE is back to $BOLD$(versions_at HEAD)$RESET, the change files are back"
}
versions_at() {
git show "$1:$VERSION_FILE" | jq -r '[paths(scalars) as $path | "\($path | join(".")) \(getpath($path))"] | join(", ")'
}
main