diff --git a/.travis.yml b/.travis.yml index 13e4e93fd7d32e6beb4ce7f33f0256e0a613f714..a3ce034131abcdc9c9ca6cf913e81fdbce7f2400 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,18 +15,31 @@ script: - SCITRAN_PERSISTENT_DB_PORT=27017 tests/bin/run-tests-ubuntu.sh after_success: + - if [ "$TRAVIS_EVENT_TYPE" == "push" -o "$TRAVIS_TAG" ]; then + SSH_KEY_FILE=$(mktemp -p $HOME/.ssh/); + + openssl aes-256-cbc -K $encrypted_55750ae1fbc7_key -iv $encrypted_55750ae1fbc7_iv -in .github_deploy_key.enc -out "$SSH_KEY_FILE" -d; + + chmod 600 "$SSH_KEY_FILE" && printf "%s\n" \ + "Host github.com" \ + " IdentityFile $SSH_KEY_FILE" \ + " LogLevel ERROR" >> ~/.ssh/config; + + git config --global user.email "travis@travis-ci.org"; + git config --global user.name "Travis CI"; + git config --global push.default simple; + fi - if [ "$TRAVIS_BRANCH" == "master" -o "$TRAVIS_EVENT_TYPE" == "pull_request" ]; then bash <(curl -s https://codecov.io/bash) -cF python; fi - if [ "$TRAVIS_TAG" ]; then ./docker/build-trigger.sh Tag "$TRAVIS_TAG" "$BUILD_TRIGGER_URL"; + ./bin/push-docs.sh "$GIT_REMOTE" tags "$TRAVIS_TAG" "Travis Core Docs Build - ${TRAVIS_BUILD_NUMBER}"; fi - if [ "$TRAVIS_EVENT_TYPE" == "push" -a "$TRAVIS_BRANCH" == "master" ]; then ./docker/build-trigger.sh Branch "$TRAVIS_BRANCH" "$BUILD_TRIGGER_URL"; - ./bin/build-docs.sh; fi - # Remove before pulling to master - - if [ "$TRAVIS_EVENT_TYPE" == "push" -a "$TRAVIS_BRANCH" == "swagger" ]; then - ./bin/build-docs.sh; + - if [ "$TRAVIS_EVENT_TYPE" == "push" -a -z "$TRAVIS_TAG" ]; then + ./bin/push-docs.sh "$GIT_REMOTE" branches "$TRAVIS_BRANCH" "Travis Core Docs Build - ${TRAVIS_BUILD_NUMBER}"; fi diff --git a/bin/build-docs.sh b/bin/build-docs.sh deleted file mode 100755 index 7c70a20d7a772444f52889528bc69d0e0dc0d51c..0000000000000000000000000000000000000000 --- a/bin/build-docs.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash -# This script will build the swagger documentation and push it to the gh-pages doc -# For now this should only be run on the master branch - -set -eu - -unset CDPATH -cd "$( dirname "${BASH_SOURCE[0]}" )/.." - -# Environment Variables: -# GIT_REMOTE: The full URL for the remote repo, including auth token -# TRAVIS_BUILD_NUMBER: The travis build number -# Args: - -# Build documentation -pushd swagger -npm install -npm run build -popd - -# Decrypt SSH Key -SSH_KEY_FILE=$(mktemp -u $HOME/.ssh/XXXXX) - -openssl aes-256-cbc -K $encrypted_55750ae1fbc7_key -iv $encrypted_55750ae1fbc7_iv -in .github_deploy_key.enc -out "$SSH_KEY_FILE" -d - -chmod 600 "$SSH_KEY_FILE" \ - && printf "%s\n" \ - "Host github.com" \ - " IdentityFile $SSH_KEY_FILE" \ - " LogLevel ERROR" >> ~/.ssh/config - -# Clone the gh-pages branch into a subdirectory (gh-pages) -git clone ${GIT_REMOTE} --branch gh-pages --single-branch gh-pages - -# Copy documentation -cp -R swagger/build/swagger-ui/* gh-pages/ - -pushd gh-pages -# Check for changes -if [[ `git status --porcelain` ]]; then - # Configure git - git config user.email "travis@travis-ci.org" - git config user.name "Travis CI" - git config --global push.default simple - - # Add any modified files, and push - git add * - git commit --message "Travis Core Docs Build: ${TRAVIS_BUILD_NUMBER}" - - # Push to remote repo - git push --quiet -fi -popd - -# Cleanup subdirectory -rm -rf gh-pages/ - diff --git a/bin/push-docs.sh b/bin/push-docs.sh new file mode 100755 index 0000000000000000000000000000000000000000..0b94d66323dcc17c674fcd87aee42abdbb36e575 --- /dev/null +++ b/bin/push-docs.sh @@ -0,0 +1,160 @@ +#!/usr/bin/env bash +# This script will build the swagger documentation and push it to the gh-pages doc +# For now this should only be run on the master branch + +set -eu + +unset CDPATH +cd "$( dirname "${BASH_SOURCE[0]}" )/.." + +# Environment Variables: +# Args: <remote> (branches|tags) <branch_or_tag_name> <commit_message> +# remote: The git remote url +# branch_or_tag: Whether docs should go into the branches or tags subdirectory +# branch_or_tag_name: The name of the tag or branch +# commit_message: The commit message + +main() { + if [ "$#" -ne 4 -o "$1" == "-h" ]; then + print_usage + fi + + GIT_REMOTE=$1 + DOCS_SUBDIR=$2 + BRANCH_NAME=$3 + COMMIT_MESSAGE=$4 + + # Determine version string + if [ "$DOCS_SUBDIR" == "branches" ]; then + COMMIT_REF="$(git rev-parse --short HEAD)" + DOC_VERSION="$BRANCH_NAME/$COMMIT_REF" + elif [ "$DOCS_SUBDIR" == "tags" ]; then + DOC_VERSION="$BRANCH_NAME" + else + print_usage + fi + + # Build documentation + ( + cd swagger + npm install + npm run build -- "--docs-version=$DOC_VERSION" + ) + + # Copy documentation + if [ "$BRANCH_NAME" == "master" ]; then + checkin_master + else + checkin_branch "$DOCS_SUBDIR/$BRANCH_NAME" + fi + + # Cleanup subdirectory + rm -rf gh-pages/ +} + +# Print usage and exit +print_usage() { + echo "Usage: $0 <remote> Branch|Tag <branch_or_tag_name> <commit_message>" + exit 1 +} + +# Prune branches in a subdirectory of gh-pages +# subdir: The subdirectory name (branches|tags) +# remote_types: The remote type for ls-remote (head|tags) +prune_branches() { + subdir=$1 + remote_types=$2 + if [ -d "gh-pages/${subdir}/" ]; then + ( + cd gh-pages + for branch_dir in ${subdir}/*; do + branch_name="$(basename ${branch_dir})" + branch_exists="$(git ls-remote --${remote_types} ${GIT_REMOTE} ${branch_name} | wc -l)" + if [ "$branch_exists" -eq 0 ]; then + echo "Pruning branch: ${branch_name}" + git rm --quiet -rf "${branch_dir}" + fi + done + ) + fi +} + +# Checkin documentation for a single branche +# target_dir: The destination directory (e.g. branches/<branch_name>) +checkin_branch() { + target_dir=$1 + # We try up to 3 times, sleeping for 3 or 7 seconds between attempts + for i in 3 7 100; do + # Allow capture of exit code of subshell + set +e + ( + set -e + + # Checkout gh-pages + rm -rf gh-pages/ + git clone ${GIT_REMOTE} --branch gh-pages --single-branch gh-pages + + # Create target directory and copy files + mkdir -p "gh-pages/${target_dir}" + cp -R swagger/build/swagger-ui/* "gh-pages/${target_dir}" + + cd gh-pages + if [ "$(git status --porcelain)" ]; then + # Add files + git add "${target_dir}*" + + # Add any modified files, and push + git commit --message "$COMMIT_MESSAGE" + + # Push to remote repo + git push --quiet + else + echo "No changes to commit" + fi + ) + if [ "$?" -eq "0" ]; then + # Success case + break + elif [ "$i" -lt 100 ]; then + # Failure case, sleep and retry + echo "Error pushing branch docs, retrying in $i seconds." + sleep $i + else + # Final failure case + echo "Could not push branch docs, exiting" + exit 1 + fi + done + + set -e +} + +# Prune non-existing branches and tags, and check-in master documentation, doing a force-push +checkin_master() { + ( + # Clone the gh-pages branch and prune any branches that don't exist in remotes + git clone ${GIT_REMOTE} --branch gh-pages --single-branch gh-pages + prune_branches branches heads + prune_branches tags tags + + # Copy currently generated documentation into gh-pages + cp -R swagger/build/swagger-ui/* gh-pages/ + cd gh-pages/ + + if [ "$(git status --porcelain)" ]; then + # Checkout a new orphan branch + git checkout --quiet --orphan gh-pages-new + # Add everything that still exists in this folder + git add * + # Commit + git commit --quiet --message "$COMMIT_MESSAGE" + # Force push to gh-pages + git push --quiet --force --set-upstream origin gh-pages-new:gh-pages + else + echo "No changes to commit" + fi + ) +} + +main "$@" +