|
| 1 | +#!/usr/bin/env bash |
| 2 | +# This script will build the swagger documentation and push it to the gh-pages doc |
| 3 | +# For now this should only be run on the master branch |
| 4 | + |
| 5 | +set -eu |
| 6 | + |
| 7 | +unset CDPATH |
| 8 | +cd "$( dirname "${BASH_SOURCE[0]}" )/.." |
| 9 | + |
| 10 | +# Environment Variables: |
| 11 | +# Args: <remote> (branches|tags) <branch_or_tag_name> <commit_message> |
| 12 | +# remote: The git remote url |
| 13 | +# branch_or_tag: Whether docs should go into the branches or tags subdirectory |
| 14 | +# branch_or_tag_name: The name of the tag or branch |
| 15 | +# commit_message: The commit message |
| 16 | + |
| 17 | +main() { |
| 18 | + if [ "$#" -ne 4 -o "$1" == "-h" ]; then |
| 19 | + print_usage |
| 20 | + fi |
| 21 | + |
| 22 | + GIT_REMOTE=$1 |
| 23 | + DOCS_SUBDIR=$2 |
| 24 | + BRANCH_NAME=$3 |
| 25 | + COMMIT_MESSAGE=$4 |
| 26 | + |
| 27 | + # Determine version string |
| 28 | + if [ "$DOCS_SUBDIR" == "branches" ]; then |
| 29 | + COMMIT_REF="$(git rev-parse --short HEAD)" |
| 30 | + DOC_VERSION="$BRANCH_NAME/$COMMIT_REF" |
| 31 | + elif [ "$DOCS_SUBDIR" == "tags" ]; then |
| 32 | + DOC_VERSION="$BRANCH_NAME" |
| 33 | + else |
| 34 | + print_usage |
| 35 | + fi |
| 36 | + |
| 37 | + # Build documentation |
| 38 | + ( |
| 39 | + cd swagger |
| 40 | + npm install |
| 41 | + npm run build -- "--docs-version=$DOC_VERSION" |
| 42 | + ) |
| 43 | + |
| 44 | + # Copy documentation |
| 45 | + if [ "$BRANCH_NAME" == "master" ]; then |
| 46 | + checkin_master |
| 47 | + else |
| 48 | + checkin_branch "$DOCS_SUBDIR/$BRANCH_NAME" |
| 49 | + fi |
| 50 | + |
| 51 | + # Cleanup subdirectory |
| 52 | + rm -rf gh-pages/ |
| 53 | +} |
| 54 | + |
| 55 | +# Print usage and exit |
| 56 | +print_usage() { |
| 57 | + echo "Usage: $0 <remote> Branch|Tag <branch_or_tag_name> <commit_message>" |
| 58 | + exit 1 |
| 59 | +} |
| 60 | + |
| 61 | +# Prune branches in a subdirectory of gh-pages |
| 62 | +# subdir: The subdirectory name (branches|tags) |
| 63 | +# remote_types: The remote type for ls-remote (head|tags) |
| 64 | +prune_branches() { |
| 65 | + subdir=$1 |
| 66 | + remote_types=$2 |
| 67 | + if [ -d "gh-pages/${subdir}/" ]; then |
| 68 | + ( |
| 69 | + cd gh-pages |
| 70 | + for branch_dir in ${subdir}/*; do |
| 71 | + branch_name="$(basename ${branch_dir})" |
| 72 | + branch_exists="$(git ls-remote --${remote_types} ${GIT_REMOTE} ${branch_name} | wc -l)" |
| 73 | + if [ "$branch_exists" -eq 0 ]; then |
| 74 | + echo "Pruning branch: ${branch_name}" |
| 75 | + git rm --quiet -rf "${branch_dir}" |
| 76 | + fi |
| 77 | + done |
| 78 | + ) |
| 79 | + fi |
| 80 | +} |
| 81 | + |
| 82 | +# Checkin documentation for a single branche |
| 83 | +# target_dir: The destination directory (e.g. branches/<branch_name>) |
| 84 | +checkin_branch() { |
| 85 | + target_dir=$1 |
| 86 | + # We try up to 3 times, sleeping for 3 or 7 seconds between attempts |
| 87 | + for i in 3 7 100; do |
| 88 | + # Allow capture of exit code of subshell |
| 89 | + set +e |
| 90 | + ( |
| 91 | + set -e |
| 92 | + |
| 93 | + # Checkout gh-pages |
| 94 | + rm -rf gh-pages/ |
| 95 | + git clone ${GIT_REMOTE} --branch gh-pages --single-branch gh-pages |
| 96 | + |
| 97 | + # Create target directory and copy files |
| 98 | + mkdir -p "gh-pages/${target_dir}" |
| 99 | + cp -R swagger/build/swagger-ui/* "gh-pages/${target_dir}" |
| 100 | + |
| 101 | + cd gh-pages |
| 102 | + if [ "$(git status --porcelain)" ]; then |
| 103 | + # Add files |
| 104 | + git add "${target_dir}*" |
| 105 | + |
| 106 | + # Add any modified files, and push |
| 107 | + git commit --message "$COMMIT_MESSAGE" |
| 108 | + |
| 109 | + # Push to remote repo |
| 110 | + git push --quiet |
| 111 | + else |
| 112 | + echo "No changes to commit" |
| 113 | + fi |
| 114 | + ) |
| 115 | + if [ "$?" -eq "0" ]; then |
| 116 | + # Success case |
| 117 | + break |
| 118 | + elif [ "$i" -lt 100 ]; then |
| 119 | + # Failure case, sleep and retry |
| 120 | + echo "Error pushing branch docs, retrying in $i seconds." |
| 121 | + sleep $i |
| 122 | + else |
| 123 | + # Final failure case |
| 124 | + echo "Could not push branch docs, exiting" |
| 125 | + exit 1 |
| 126 | + fi |
| 127 | + done |
| 128 | + |
| 129 | + set -e |
| 130 | +} |
| 131 | + |
| 132 | +# Prune non-existing branches and tags, and check-in master documentation, doing a force-push |
| 133 | +checkin_master() { |
| 134 | + ( |
| 135 | + # Clone the gh-pages branch and prune any branches that don't exist in remotes |
| 136 | + git clone ${GIT_REMOTE} --branch gh-pages --single-branch gh-pages |
| 137 | + prune_branches branches heads |
| 138 | + prune_branches tags tags |
| 139 | + |
| 140 | + # Copy currently generated documentation into gh-pages |
| 141 | + cp -R swagger/build/swagger-ui/* gh-pages/ |
| 142 | + cd gh-pages/ |
| 143 | + |
| 144 | + if [ "$(git status --porcelain)" ]; then |
| 145 | + # Checkout a new orphan branch |
| 146 | + git checkout --quiet --orphan gh-pages-new |
| 147 | + # Add everything that still exists in this folder |
| 148 | + git add * |
| 149 | + # Commit |
| 150 | + git commit --quiet --message "$COMMIT_MESSAGE" |
| 151 | + # Force push to gh-pages |
| 152 | + git push --quiet --force --set-upstream origin gh-pages-new:gh-pages |
| 153 | + else |
| 154 | + echo "No changes to commit" |
| 155 | + fi |
| 156 | + ) |
| 157 | +} |
| 158 | + |
| 159 | +main "$@" |
| 160 | + |
0 commit comments