#!/bin/bash -e # # Deploy your branch on VIP Go. # # This script uses various CircleCI, Travis CI or GitHub Actions environment # variables. CircleCI prefix their environment variables with # `CIRCLE_`, Travis with `TRAVIS_`, and GitHub Actions with `GITHUB_`. # Documentation: # https://circleci.com/docs/2.0/env-vars/#circleci-built-in-environment-variables # https://docs.travis-ci.com/user/environment-variables/ # https://docs.github.com/en/actions/learn-github-actions/environment-variables set -ex # The deploy suffix flexibility is mainly here to allow # us to test Circle and Travis builds simultaneously on # the https://github.com/Automattic/vip-go-skeleton/ repo. DEPLOY_SUFFIX="${VIP_DEPLOY_SUFFIX:--built}" if [ -n "$CIRCLECI" ]; then BRANCH="$CIRCLE_BRANCH" REPO_SLUG="${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}" COMMIT_SHA="$CIRCLE_SHA1" # SRC_DIR="$CIRCLE_WORKING_DIRECTORY" SRC_DIR="$PWD" BUILD_URL="$CIRCLE_BUILD_URL" elif [ -n "$TRAVIS" ]; then BRANCH="$TRAVIS_BRANCH" REPO_SLUG="$TRAVIS_REPO_SLUG" COMMIT_SHA="$TRAVIS_COMMIT" SRC_DIR="$TRAVIS_BUILD_DIR" BUILD_URL="$TRAVIS_BUILD_WEB_URL" elif [ -n "$GITHUB_ACTIONS" ]; then BRANCH="$GITHUB_REF_NAME" REPO_SLUG="$GITHUB_REPOSITORY" COMMIT_SHA="$GITHUB_SHA" SRC_DIR="$GITHUB_WORKSPACE" BUILD_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}" REPO_SSH_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" else echo "Unknown CI environment, exiting." exit 1 fi BUILD_DIR="/tmp/vip-go-build-$(date +%s)" REPO_SSH_URL="${REPO_SSH_URL:-"git@github.com:${REPO_SLUG}"}" DEPLOY_BRANCH="${BRANCH}${DEPLOY_SUFFIX}" cd "$SRC_DIR" COMMIT_AUTHOR_NAME="$( git log --format=%an -n 1 "${COMMIT_SHA}" )" COMMIT_AUTHOR_EMAIL="$( git log --format=%ae -n 1 "${COMMIT_SHA}" )" COMMIT_COMMITTER_NAME="$( git log --format=%cn -n 1 "${COMMIT_SHA}" )" COMMIT_COMMITTER_EMAIL="$( git log --format=%ce -n 1 "${COMMIT_SHA}" )" # Run some checks # --------------- if [ -n "$TRAVIS" ] && [ -n "$CIRCLECI" ] && [ -n "$GITHUB_ACTIONS" ]; then echo "ERROR: this script requires either CircleCI, Travis CI, or GitHub Actions" echo "You will need to amend the setup above to set the required variables from the information specific to your CI service or tool." exit 1 fi if [ -z "${BRANCH}" ]; then echo "ERROR: No branch specified!" echo "This variable should be set by Travis CI, CircleCI, and GitHub Actions; if you consistently experience errors please check with WordPress.com VIP support." exit 1 fi if [ -d "$BUILD_DIR" ]; then echo "ERROR: ${BUILD_DIR} already exists." echo "This should not happen, if you consistently experience errors please check with WordPress.com VIP support." exit 1 fi if [[ "${BRANCH}" == *${DEPLOY_SUFFIX} ]]; then echo "NOTICE: Attempting to build from branch '${BRANCH}' to deploy '${DEPLOY_BRANCH}', seems like recursion so aborting." echo "This is a protective measure, no action is required." exit 0 fi if [[ -n $TRAVIS ]] && [ "$TRAVIS_PULL_REQUEST" != 'false' ]; then echo "NOTICE: Aborting a build to '${DEPLOY_BRANCH}' from a pull request on '${BRANCH}', only build from merges directly to the branch" echo "This is a protective measure, no action is required." exit 0 fi # Everything seems OK, getting the built repo sorted # -------------------------------------------------- echo "Deploying ${BRANCH} to ${DEPLOY_BRANCH}" # Making the directory we're going to sync the build into git init "${BUILD_DIR}" cd "${BUILD_DIR}" if [ -n "${GITHUB_AUTH_TOKEN}" ]; then git config --local http.https://github.com/.extraheader "Authorization: basic ${GITHUB_AUTH_TOKEN}" fi git remote add origin "${REPO_SSH_URL}" if [[ 0 = $(git ls-remote --heads "${REPO_SSH_URL}" "${DEPLOY_BRANCH}" | wc -l) ]]; then echo -e "\nCreating a ${DEPLOY_BRANCH} branch..." git checkout --quiet --orphan "${DEPLOY_BRANCH}" else echo "Using existing ${DEPLOY_BRANCH} branch" git fetch origin "${DEPLOY_BRANCH}" --depth=1 git checkout --quiet "${DEPLOY_BRANCH}" fi # Expand all submodules git submodule update --init --recursive; # Copy the files over # ------------------- if ! command -v 'rsync'; then APT_GET_PREFIX='' if command -v 'sudo'; then APT_GET_PREFIX='sudo' fi $APT_GET_PREFIX apt-get update $APT_GET_PREFIX apt-get install -q -y rsync fi echo "Syncing files... quietly" rsync --delete -a "${SRC_DIR}/" "${BUILD_DIR}" --exclude='.git/' # gitignore override # To allow commiting built files in the build branch (which are typically ignored) # ------------------- BUILD_DEPLOYIGNORE_PATH="${BUILD_DIR}/.deployignore" if [ -f "$BUILD_DEPLOYIGNORE_PATH" ]; then BUILD_GITIGNORE_PATH="${BUILD_DIR}/.gitignore" if [ -f "$BUILD_GITIGNORE_PATH" ]; then rm "$BUILD_GITIGNORE_PATH" fi echo "-- found .deployignore; emptying all gitignore files" find "$BUILD_DIR" -type f -name '.gitignore' | while read GITIGNORE_FILE; do echo "# Emptied by vip-go-build; '.deployignore' exists and used as global .gitignore. See https://wp.me/p9nvA-89A" > "$GITIGNORE_FILE" echo "${GITIGNORE_FILE}" done echo "-- using .deployignore as global .gitignore" mv "$BUILD_DEPLOYIGNORE_PATH" "$BUILD_GITIGNORE_PATH" fi # Make up the commit, commit, and push # ------------------------------------ # Set Git committer git config user.name "${COMMIT_COMMITTER_NAME}" git config user.email "${COMMIT_COMMITTER_EMAIL}" # Add changed files, delete deleted, etc, etc, you know the drill git add -A . if [ -z "$(git status --porcelain)" ]; then echo "NOTICE: No changes to deploy" exit 0 fi # Commit it. MESSAGE=$( printf 'Build changes from %s\n\n%s' "${COMMIT_SHA}" "${BUILD_URL}" ) # Set the Author to the commit (expected to be a client dev) and the committer # will be set to the default Git user for this CI system git commit --author="${COMMIT_AUTHOR_NAME} <${COMMIT_AUTHOR_EMAIL}>" -m "${MESSAGE}" # Push it (push it real good). git push origin "${DEPLOY_BRANCH}"