131 lines
3.5 KiB
Bash
Executable File
131 lines
3.5 KiB
Bash
Executable File
#!/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"
|
|
FLAG="$3"
|
|
REPO_NAME="$4"
|
|
BINNAME="$0"
|
|
usage() { echo "usage: $BINNAME <packagespec version> <branch name> [-pr PRODUCT_NAME]"; }
|
|
|
|
if [ -z "$VERSION" ]; then
|
|
usage; exit 1
|
|
fi
|
|
if [ -z "$BRANCH" ]; then
|
|
usage; exit 1
|
|
fi
|
|
PR=false
|
|
if [ -n "$FLAG" ]; then
|
|
if [ "$FLAG" = "-pr" ]; then
|
|
if [ -z "$REPO_NAME" ]; then
|
|
usage; exit 1
|
|
fi
|
|
PR=true
|
|
else
|
|
usage; exit 1
|
|
fi
|
|
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"
|
|
|
|
if ! $PR; then
|
|
exit 0
|
|
fi
|
|
|
|
# Open browser with PR ready:
|
|
open https://github.com/hashicorp/$REPO_NAME/compare/$BRANCH...$NEW_BRANCH?expand=1
|