Created
February 16, 2016 18:41
-
-
Save pjcdawkins/2accd36f0014bc5f3ae2 to your computer and use it in GitHub Desktop.
This file contains 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
#!/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