Skip to content

Instantly share code, notes, and snippets.

@pjcdawkins
Created February 16, 2016 18:41
Show Gist options
  • Save pjcdawkins/2accd36f0014bc5f3ae2 to your computer and use it in GitHub Desktop.
Save pjcdawkins/2accd36f0014bc5f3ae2 to your computer and use it in GitHub Desktop.
#!/bin/bash
set -e
### ABOUT ###
# This is a Jenkins build script which integrates with the GitHub Pull Request
# Builder plugin.
### ENVIRONMENT VARIABLES ###
# PF_PROJECT_ID Required: your Platform.sh project ID.
# PF_CLUSTER Required: the cluster for your project ('eu' or 'us').
# GH_BOT_NAME Optional: a username for your GitHub bot (with access to create commit statuses).
# GH_BOT_PASSWORD Optional: the password for your GitHub bot.
# Get parameters from the Github Pull Request Builder plugin.
GIT_BRANCH=$ghprbSourceBranch
GH_PR_URL=$ghprbPullLink
GH_COMMIT_SHA=$ghprbActualCommit
GH_OWNER=`echo "$GH_PR_URL" | cut -d'/' -f 4`
GH_REPO=`echo "$GH_PR_URL" | cut -d'/' -f 5`
GH_PR_NUM=`echo "$GH_PR_URL" | cut -d'/' -f 7`
PF_PARENT_ENV=$ghprbTargetBranch
# Function to update the commit status. Takes 3 arguments: commit state,
# description, and target_url.
gh_update_status() {
STATE=$1
MESSAGE=$2
URL=$3
CONTEXT='continuous-integration/platform-github'
if [ -z "$GH_BOT_NAME" ] || [ -z "$GH_BOT_PASSWORD" ]; then
# If bot credentials are not available, print the message.
echo "$MESSAGE";
return;
fi
echo "Creating GitHub commit state: '$STATE' ('$MESSAGE')"
curl -s -u"$GH_BOT_NAME:$GH_BOT_PASSWORD" \
-XPOST https://api.github.com/repos/$GH_OWNER/$GH_REPO/statuses/$GH_COMMIT_SHA \
-d"{\"state\":\"$STATE\",\"description\":\"$MESSAGE\",\"target_url\":\"$URL\",\"context\":\"$CONTEXT\"}" > /dev/null
}
# Set up error handling for the rest of the script, providing a pull request comment.
ERROR_MESSAGE=''
error() {
gh_update_status error "Line $1 returned exit code $2: $ERROR_MESSAGE"
exit 1
}
# Any processes following this which return a non-zero exit code will trigger
# the error() function.
trap 'error $LINENO $?' ERR
# This script is not for production deployments.
if [ "$GIT_BRANCH" = "master" ]; then
echo "Not pushing master branch."
exit
fi
# Platform requires sanitized branch machine names.
sanitize() {
local SANITIZED=$(echo "$1" | tr [A-Z] [a-z])
local SANITIZED=${SANITIZED//[^a-z0-9\-]/}
local SANITIZED=${SANITIZED:0:32}
echo "$SANITIZED"
}
PF_PARENT_ENV=`sanitize $PF_PARENT_ENV`
PF_BRANCH=`sanitize $GIT_BRANCH`
if [ "$PF_BRANCH" != "$GIT_BRANCH" ]; then
echo "Branch name sanitized: using environment ID '$PF_BRANCH' for branch '$GIT_BRANCH'"
fi
PF_GIT_URL="$PF_PROJECT_ID@git.$PF_CLUSTER.platform.sh:$PF_PROJECT_ID.git"
PF_PUBLIC_URL="http://$PF_BRANCH-$PF_PROJECT_ID.$PF_CLUSTER.platform.sh/"
PF_ADMIN_URL="https://$PF_CLUSTER.platform.sh/projects/$PF_PROJECT_ID/environments/$PF_BRANCH"
echo "Platform Git URL: $PF_GIT_URL"
echo "Platform public URL: $PF_PUBLIC_URL"
echo "Platform admin URL: $PF_ADMIN_URL"
# Check if the Platform CLI exists, in the PATH.
PLATFORM=$(command -v platform >/dev/null 2>&1) || true
# Or perhaps it's in the user's global Composer directory.
if [ -z "$PLATFORM" ] && [ -f ~/.composer/vendor/bin/platform ]; then
PLATFORM=~/.composer/vendor/bin/platform
fi
# Otherwise, install Composer first, and use that to install the Platform CLI.
ERROR_MESSAGE='Failed to install the Platform.sh CLI'
if [ -z "$PLATFORM" ]; then
COMPOSER=$(command -v composer >/dev/null 2>&1) || true
if [ -z "$COMPOSER" ] && [ ! -f .build/composer.phar ]; then
mkdir -p .build
curl -sS https://getcomposer.org/composer.phar > .build/composer.phar
COMPOSER="php .build/composer.phar"
fi
$COMPOSER global require "platformsh/cli:1.*"
PLATFORM=~/.composer/vendor/bin/platform
fi
ERROR_MESSAGE=''
# Add a Git remote for Platform.
git remote add platform $PF_GIT_URL 2>/dev/null || true
# Check whether the environment already exists on Platform.
ENV_EXISTS=false
ENVS_AVAILABLE=`$PLATFORM environments --project=$PF_PROJECT_ID --pipe`
for PF_ENV in $ENVS_AVAILABLE; do
if [ "$PF_ENV" = "$PF_BRANCH" ]; then ENV_EXISTS=true; break; fi
done
# Check whether the parent environment exists on Platform.
PARENT_ENV_EXISTS=false
for PF_ENV in $ENVS_AVAILABLE; do
if [ "$PF_ENV" = "$PF_PARENT_ENV" ]; then PARENT_ENV_EXISTS=true; break; fi
done
if [ "$PARENT_ENV_EXISTS" = false ]; then
gh_update_status error "Parent environment not found: $PF_PARENT_ENV"
exit 1
fi
if [ "$ENV_EXISTS" = true ]; then
gh_update_status pending "Updating Platform.sh environment $PF_BRANCH" "$PF_ADMIN_URL"
# If the environment already exists, ensure that it is activated, and re-sync
# its data. We assume that the parent of this environment (the sync source) is
# correct.
ERROR_MESSAGE="Failed to activate $PF_BRANCH"
$PLATFORM environment:activate --yes --project=$PF_PROJECT_ID --environment=$PF_BRANCH
ERROR_MESSAGE=''
# @todo Solve the problem of asynchronous synchronization: at the moment
# the CLI makes the 'synchronize' API call and returns without waiting for
# the whole sync process to finish.
echo "Syncing data for $PF_BRANCH..."
ERROR_MESSAGE="Failed to synchronize data for $PF_BRANCH"
$PLATFORM environment:synchronize --yes --project=$PF_PROJECT_ID --environment=$PF_BRANCH data
ERROR_MESSAGE=''
else
# Create a new Platform environment, branched from the parent.
echo "Creating Platform environment $PF_BRANCH, branched from $PF_PARENT_ENV..."
gh_update_status pending "Creating Platform.sh environment $PF_BRANCH, branched from $PF_PARENT_ENV" "$PF_ADMIN_URL"
ERROR_MESSAGE="Failed to branch new environment $PF_BRANCH"
$PLATFORM branch --force --project=$PF_PROJECT_ID --environment=$PF_PARENT_ENV $PF_BRANCH
ERROR_MESSAGE=''
fi
# Push the commit to Platform. This will trigger the build process.
echo "Pushing changes to Platform ($PF_GIT_URL)..."
ERROR_MESSAGE="Failed to push $PF_BRANCH to Platform.sh"
exec 3>&1
GIT_OUTPUT=$(git push --force platform HEAD:$PF_BRANCH 2>&1 | tee >(cat - >&3))
ERROR_MESSAGE=''
# Check for a push error in the Git log.
GIT_ERROR=$(grep -m 1 -i 'error: unable to push' <<< "$GIT_OUTPUT") || true
if [ ! -z "$GIT_ERROR" ]; then
gh_update_status error "Git error: $GIT_ERROR"
exit 1
fi
# Check for build errors in the Git log.
BUILD_ERROR=$(grep -m 1 'Error building' <<< "$GIT_OUTPUT") || true
if [ ! -z "$BUILD_ERROR" ]; then
gh_update_status error "Build error: $BUILD_ERROR"
exit 1
fi
# The build was successful.
if [ "$ENV_EXISTS" = true ]; then
gh_update_status success "Updated Platform.sh environment $PF_BRANCH" "$PF_PUBLIC_URL"
else
gh_update_status success "Deployed Platform.sh environment $PF_BRANCH" "$PF_PUBLIC_URL"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment