A
Austin Songer, CISSP
Guest
- Thread Author
- #1
create-release-and-mergebacks.sh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Show hidden characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Show hidden characters
| #!/usr/bin/env bash |
| RED='\033[0;31m' |
| YELLOW='\033[1;93m' |
| PURPLE='\033[0;35m' |
| GREEN='\033[0;32m' |
| BLUE='\033[0;94m' |
| NC='\033[0m' # No Color |
| APP_FNAME=$(basename -- "$0") |
| APP="${APP_FNAME%.*}" |
| function initBranches() { |
| export MAIN= |
| export STAGING= |
| export PRODUCTION= |
| } |
| function setupBranches() { |
| [ ! -f .branches.env ] || export $(grep -v '^#' .branches.env | xargs) |
| if [ -z "$MAIN" ]; then |
| export MAIN=main; |
| fi |
| if [ -z "$STAGING" ]; then |
| export STAGING=staging; |
| fi |
| if [ -z "$PRODUCTION" ]; then |
| export PRODUCTION=production; |
| fi |
| # echo -e $GREEN $PWD $PURPLE MAIN=$MAIN, STAGING=$STAGING, PRODUCTION=$PRODUCTION $NC |
| } |
| export SPRINT=$1 |
| if [ -z "$SPRINT" ]; then |
| echo -e $RED please run $0 SPRINT \( gitPreRelease \| gitRelease \| gitMergeBackProdToStage \| gitMergeBackStageToDev \) $NC |
| exit 30; |
| fi |
| shift |
| if [ -z "$ACTION" ]; then |
| export ACTION=$1; |
| fi |
| if [ -z "$ACTION" ]; then |
| echo -e $RED please run $0 $SPRINT \( gitPreRelease \| gitRelease \| gitMergeBackProdToStage \| gitMergeBackStageToDev \) $NC |
| exit 30; |
| fi |
| if [ "$#" -gt 0 ]; then shift; fi |
| if [ -z "$FOLDER_NAME" ]; then |
| export FOLDER_NAME=$1; |
| fi; |
| if [ -z "$FOLDER_NAME" ]; then |
| export FOLDER_NAME=~/git |
| fi |
| installer=`which brew` |
| which gh >/dev/null || $installer install gh |
| if [ $? -ne 0 ]; then |
| if [ -z "$installer" ] ; then |
| echo -e $RED Unable to install gh, unable to find an installer.$NC |
| echo -e $RED Get yourself one of brew, yum, or apt!$NC |
| echo Someone told me that you can install brew simply running this: |
| echo -e $YELLOW '/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"' $NC |
| echo -e $YELLOW 'echo "$(brew shellenv)" >> ~/.bash_profile' $NC |
| echo -e $YELLOW 'eval "$(brew shellenv)"' $NC |
| echo Try and tell me... |
| exit 82 |
| fi |
| echo -e $RED unable to install gh, please run $installer install gh $NC |
| exit 67 |
| fi |
| function gitLastUpdated() { |
| SRC=$1 |
| TARGET=$2 |
| echo -e $BLUE last updated: |
| gh pr list -H $SRC -B $TARGET --json commits -q ".[0].commits | map( select(.messageHeadline | startswith(\"Merge\") | not ) ) | max_by(.committedDate) | .committedDate" |
| echo -e $NC |
| } |
| function gitPreRelease() { |
| SRC=$MAIN |
| TARGET=$STAGING |
| ACTION_NAME=Pre-release |
| echo -e $BLUE Creating $ACTION_NAME: $NC |
| gh pr create -a @me -H $SRC -B $TARGET -t "Sprint $SPRINT: $ACTION_NAME" --body "Sprint $SPRINT: $ACTION_NAME" |
| echo -e $BLUE --- --- --- --- --- $NC |
| PR_URL=$(gh pr list -H $SRC -B $TARGET --json url -q '.[0].url') |
| if [ -z "$PR_URL" ] ; then |
| echo -e $RED $ACTION_NAME Failed : not created $NC |
| echo -e $RED --- --- --- --- --- $NC |
| return $RES |
| fi |
| echo -e $GREEN ~~~ $ACTION_NAME: Created ~~~ $NC |
| echo -e $BLUE $ACTION_NAME: $PR_URL $NC |
| gitLastUpdated $SRC $TARGET |
| } |
| function gitStatus() { |
| git status |
| } |
| function gitRelease() { |
| TARGET=$PRODUCTION |
| SRC=$STAGING |
| ACTION_NAME=Release |
| echo -e $BLUE Creating $ACTION_NAME: $NC |
| gh pr create -a @me -H $SRC -B $TARGET -l production -l release -t "Sprint $SPRINT: $ACTION_NAME" --body "Sprint $SPRINT: $ACTION_NAME" |
| echo -e $BLUE --- --- --- --- --- $NC |
| PR_URL=$(gh pr list -H $SRC -B $TARGET --json url -q '.[0].url') |
| if [ -z "$PR_URL" ] ; then |
| echo -e $RED $ACTION_NAME Failed : not created $NC |
| echo -e $RED --- --- --- --- --- $NC |
| return $RES |
| fi |
| echo -e $GREEN ~~~ $ACTION_NAME: Created ~~~ $NC |
| echo -e $BLUE $ACTION_NAME: $PR_URL $NC |
| gitLastUpdated $SRC $TARGET |
| } |
| function gitMergeBackProdToStage() { |
| SRC=$PRODUCTION |
| TARGET=$STAGING |
| MERGE_BACK=mergeback/$SPRINT/$SRC-$TARGET-mergeback-$SPRINT |
| gitMergeBack $SRC $TARGET $MERGE_BACK |
| } |
| function gitQuickMergeBackProductionToStaging() { |
| SRC=$PRODUCTION |
| TARGET=$STAGING |
| gh pr create -a @me -H $SRC -B $TARGET -t "Sprint $SPRINT: $SRC to $TARGET merge back" --body "Sprint $SPRINT: $SRC to $TARGET merge back" |
| gitLastUpdated $SRC $TARGET |
| } |
| function gitQuickCloseMergeBackProductionToStaging() { |
| SRC=$PRODUCTION |
| TARGET=$STAGING |
| gitCloseMergeBack $TARGET $SRC |
| } |
| function gitQuickMergeBackStagingToMain() { |
| SRC=$STAGING |
| TARGET=$MAIN |
| gh pr create -a @me -H $SRC -B $TARGET -t "Sprint $SPRINT: $SRC to $TARGET merge back" --body "Sprint $SPRINT: $SRC to $TARGET merge back" |
| gitLastUpdated $SRC $TARGET |
| } |
| function gitQuickCloseMergeBackStagingToMain() { |
| SRC=$STAGING |
| TARGET=$MAIN |
| gitCloseMergeBack $TARGET $SRC |
| } |
| function gitCloseMergeBackProdToStage() { |
| SRC=$PRODUCTION |
| TARGET=$STAGING |
| MERGE_BACK=mergeback/$SPRINT/$SRC-$TARGET-mergeback-$SPRINT |
| gitCloseMergeBack $TARGET $MERGE_BACK |
| } |
| function gitMergeBackStageToDev() { |
| SRC=$STAGING |
| TARGET=$MAIN |
| MERGE_BACK=mergeback/$SPRINT/$SRC-$TARGET-mergeback-$SPRINT |
| gitMergeBack $SRC $TARGET $MERGE_BACK |
| } |
| function gitCloseMergeBackStageToDev() { |
| SRC=$STAGING |
| TARGET=$MAIN |
| MERGE_BACK=mergeback/$SPRINT/$SRC-$TARGET-mergeback-$SPRINT |
| gitCloseMergeBack $TARGET $MERGE_BACK |
| } |
| function gitMergeBack() { |
| SRC=$1 |
| TARGET=$2 |
| MERGE_BACK=$3 |
| echo -e $YELLOW --- gitMergeBack $SRC to $TARGET - $BLUE $MERGE_BACK --- $NC |
| PREV_SRC=`git branch --show-current` |
| git fetch origin $TARGET:$TARGET |
| git fetch origin $SRC:$SRC |
| git branch -D -r $MERGE_BACK & git push |
| git checkout -B $MERGE_BACK $TARGET |
| git merge --no-edit -m "Merge - $SRC to $TARGET (merge back)" $SRC |
| if [ $? -eq 0 ]; then |
| git push --set-upstream origin $MERGE_BACK |
| gh pr create -a @me -H $MERGE_BACK -B $TARGET -t "Sprint $SPRINT: $SRC to $TARGET merge back" --body "Sprint $SPRINT: $SRC to $TARGET merge back" |
| if [ $? -eq 0 ]; then |
| echo -e $GREEN $PWD ~~~ Created ~~~ $NC |
| gitLastUpdated $MERGE_BACK $TARGET |
| else |
| echo -e $PURPLE $PWD ~~~ Not Created ~~~ $NC |
| git branch -D -r $MERGE_BACK |
| git push origin -d $MERGE_BACK |
| git checkout $PREV_SRC |
| fi |
| else |
| echo -e $RED ~~~ Please fix the conflicts ~~~ $NC |
| fi |
| } |
| function gitCloseMergeBack() { |
| TARGET=$1 |
| MERGE_BACK=$2 |
| echo -e $YELLOW --- Close Merge Backs $MERGE_BACK =\> $TARGET $SRC --- $NC |
| PR_URL=$(gh pr list -H $MERGE_BACK -B $TARGET --json url -q '.[0].url') |
| if [ "$PR_URL" != "" ]; then |
| if [ "$MERGE_BACK" != "$PRODUCTION" ] && [ "$MERGE_BACK" != "$STAGING" ] && [ "$MERGE_BACK" != "$MAIN" ]; then |
| SHOULD_DELETE=-d |
| fi |
| echo -e $BLUE +++ URL : $PR_URL +++ $NC |
| gh pr close $PR_URL $SHOULD_DELETE -c "Automatically closed by $APP" |
| git pull |
| git prune |
| else |
| echo -e $YELLOW --- Close Merge Backs nothing to do! $SRC $TARGET $SRC --- $NC |
| fi |
| } |
| function gitCloseReleasePreRelease() { |
| SRC=$1 |
| TARGET=$2 |
| echo -e $YELLOW --- Close Release/Pre Release $SRC =\> $TARGET $SRC --- $NC |
| PR_URL=$(gh pr list -H $SRC -B $TARGET --json url -q '.[0].url') |
| if [ "$PR_URL" != "" ]; then |
| echo -e $BLUE +++ URL : $PR_URL +++ $NC |
| if [ "$MERGE_BACK" != "$PRODUCTION" ] && [ "$MERGE_BACK" != "$STAGING" ] && [ "$MERGE_BACK" != "$MAIN" ]; then |
| SHOULD_DELETE=-d |
| fi |
| gh pr close $PR_URL $SHOULD_DELETE -c "Automatically closed by $APP" |
| git pull |
| git prune |
| else |
| echo -e $YELLOW --- Close Release/Pre Release nothing to do! $SRC $TARGET $SRC --- $NC |
| fi |
| } |
| function gitCloseRelease() { |
| gitCloseReleasePreRelease $STAGING $PRODUCTION |
| } |
| function gitClosePreRelease() { |
| gitCloseReleasePreRelease $MAIN $STAGING |
| } |
| function gitStartDevelopingAgain() { |
| git checkout $MAIN |
| git pull -p |
| git prune |
| } |
| function pushd_ () { |
| command pushd "$@" > /dev/null || exit |
| } |
| function popd_ () { |
| command popd > /dev/null || exit |
| } |
| pushd_ $FOLDER_NAME || exit |
| clear |
| echo -e $BLUE -+-+-+- $APP -+-+-+- $NC |
| for f in `cat services.list`; do |
| initBranches |
| setupBranches |
| DIR_NAME=$(basename -- "$f") |
| DIR="${DIR_NAME%.*}" |
| if [[ -d $f ]]; then |
| # $f is a directory, but skip if you can't pushd to it |
| pushd_ "$f" || continue |
| setupBranches |
| echo -e $GREEN +-+-+-+ Running $BLUE $ACTION $GREEN on $BLUE $DIR $GREEN +-+-+- $NC |
| # Change this to the required action |
| eval "$ACTION" |
| if [ $? -eq 0 ]; then |
| echo -e $GREEN +-+-+-+ SUCCESS: $BLUE $ACTION $GREEN on $BLUE $DIR $GREEN +-+-+- $NC |
| else |
| echo -e $RED +-+-+-+ FAILED: $BLUE $ACTION $RED on $BLUE $DIR $RED +-+-+- $NC |
| fi |
| popd_ |
| fi |
| done |
| echo -e $GREEN ~~ DONE ~~ $NC |
| popd_ |