add scripts/upgrade-packagespec (#10276)

* add scripts/upgrade-packagespec

* upgrade-packagespec script: docs + actionable logs

* upgrade-packagespec script: escape branch name

- This is now more accurate and handles branch names with
  slashes and pluses better.

* Update scripts/upgrade-packagespec

Co-authored-by: Nick Cabatoff <ncabatoff@hashicorp.com>

Co-authored-by: Nick Cabatoff <ncabatoff@hashicorp.com>
This commit is contained in:
Sam Salisbury
2021-04-26 11:53:00 +01:00
committed by GitHub
parent efd19a21d5
commit ab9ed405cb

110
scripts/upgrade-packagespec Executable file
View File

@@ -0,0 +1,110 @@
#!/usr/bin/env bash
# This script takes 2 positional args:
#
# 1: The version of packagespec to upgrade a branch to (e.g. 1.2.3)
# 2: The target branch to upgrade.
#
# It works in a temp directory, so does not interfere with your work tree
# or git index or config.
#
# It does this:
#
# 1. Inspects your remote config for URL remotes.
# 2. Clone this directory into a temp dir.
# 3. Sets the remotes in the clone to match the remotes you have configured.
# 4. Fetches everything from all remotes.
# 5. Determines which remote your target branch is on. If it's more than one
# remote, then exits with an error as there would be no way to choose.
# 6. Checks out a new branch named packagespec<version>/<target branch name>
# 7. Runs packagespec upgrade -version <version>
# 8. Commits the relevant paths with the message 'packagespec upgrade -version <version>'
# 9. Pushes the new branch to the same remote as the original branch.
# 0. Tells you to open a PR.
# VERSION is the packagespec version to upgrade to.
VERSION="$1"
BRANCH="$2"
if [ -z "$VERSION" ]; then
echo "usage: $0 <packagespec version> <branch name>"
exit 1
fi
if [ -z "$BRANCH" ]; then
echo "usage: $0 <packagespec version> <branch name>"
exit 1
fi
set -euo pipefail
declare -A REMOTES
# url_remotes lists remotes along with their push URLs, where they are
# not filesystem paths (i.e. do not start with / or . ).
url_remotes() { git remote -v | grep -F "(push)" | sed -E 's/[[:space:]]+\(push\)//g' | grep -Ev "\t(/|\.)"; }
for R in $(url_remotes | cut -f1); do
REMOTES[$R]="$(url_remotes | grep -E "^$R\t" | cut -f2)"
done
for R in "${!REMOTES[@]}"; do
echo "Remote: $R = ${REMOTES[$R]}"
done
TEMP=".upgrade-packagespec"
mkdir -p "$TEMP"
echo "*" > "$TEMP/.gitignore"
CLONEDIR="$TEMP/product-repo"
if ! [ -d "$CLONEDIR/.git" ]; then
git clone . "$CLONEDIR"
fi
cd "$CLONEDIR"
echo "==> WORKING IN TEMP DIR: $CLONEDIR"
git reset --hard
# Remove existing remotes
for R in $(git remote); do git remote rm "$R"; done
# Add remotes from original checkout dir
for R in "${!REMOTES[@]}"; do
git remote add "$R" "${REMOTES[$R]}"
done
# Fetch everything from these remotes, ignore errors.
git remote update || true
BRANCH_ESCAPED="$(sed -E -e 's/\./\\./g' -e 's/\+/\\+/g' -e 's/\//\\\//g' <<< "$BRANCH")"
# Determine which remotes the branch is on.
declare -A BRANCH_REMOTES
for R in "${!REMOTES[@]}"; do
if git branch -a | grep -E "^[[:space:]]*remotes/$R/$BRANCH_ESCAPED\$"; then
TARGET_REMOTE="$R"
BRANCH_REMOTES[$R]=1
fi
done
COUNT="${#BRANCH_REMOTES[@]}"
if [ "$COUNT" -ne "1" ]; then
echo "==> ERROR: Branch $BRANCH found on $COUNT remotes; want exactly 1"
exit 1
fi
# Checkout the target update branch.
git checkout "$BRANCH"
git reset --hard "$TARGET_REMOTE/$BRANCH"
NEW_BRANCH="packagespec$VERSION/$BRANCH"
git checkout -B "$NEW_BRANCH" "$BRANCH"
COMMAND="packagespec upgrade -version $VERSION"
echo "==> Running $COMMAND"
$COMMAND
git add .circleci/ packages*.lock packagespec*
git commit -m "$COMMAND"
git push -u "$TARGET_REMOTE" "$NEW_BRANCH"
echo "==> All done: upgrade pushed to branch $NEW_BRANCH on ${REMOTES[$TARGET_REMOTE]}"
echo "==> ACTIONS FOR YOU: Open a PR with base: $BRANCH compare: $NEW_BRANCH"