github.com/sl1pm4t/consul@v1.4.5-0.20190325224627-74c31c540f9c/website/scripts/deploy.sh (about) 1 #!/usr/bin/env bash 2 set -e 3 4 PROJECT="consul" 5 PROJECT_URL="www.consul.io" 6 FASTLY_SERVICE_ID="7GrxRJP3PVBuqQbyxYQ0MV" 7 FASTLY_DICTIONARY_ID="7d0yAgSHAQ2efWKeUC3kqW" 8 9 # Ensure the proper AWS environment variables are set 10 if [ -z "$AWS_ACCESS_KEY_ID" ]; then 11 echo "Missing AWS_ACCESS_KEY_ID!" 12 exit 1 13 fi 14 15 if [ -z "$AWS_SECRET_ACCESS_KEY" ]; then 16 echo "Missing AWS_SECRET_ACCESS_KEY!" 17 exit 1 18 fi 19 20 # Ensure the proper Fastly keys are set 21 if [ -z "$FASTLY_API_KEY" ]; then 22 echo "Missing FASTLY_API_KEY!" 23 exit 1 24 fi 25 26 # Ensure we have s3cmd installed 27 if ! command -v "s3cmd" >/dev/null 2>&1; then 28 echo "Missing s3cmd!" 29 exit 1 30 fi 31 32 # Get the parent directory of where this script is and cd there 33 DIR="$(cd "$(dirname "$(readlink -f "$0")")/.." && pwd)" 34 35 # Delete any .DS_Store files for our OS X friends. 36 find "$DIR" -type f -name '.DS_Store' -delete 37 38 # Upload the files to S3 - we disable mime-type detection by the python library 39 # and just guess from the file extension because it's surprisingly more 40 # accurate, especially for CSS and javascript. We also tag the uploaded files 41 # with the proper Surrogate-Key, which we will later purge in our API call to 42 # Fastly. 43 if [ -z "$NO_UPLOAD" ]; then 44 echo "Uploading to S3..." 45 46 # Check that the site has been built 47 if [ ! -d "$DIR/build" ]; then 48 echo "Missing compiled website! Run 'make build' to compile!" 49 exit 1 50 fi 51 52 # Set browser-side cache-control to ~4h, but tell Fastly to cache for much 53 # longer. We manually purge the Fastly cache, so setting it to a year is more 54 # than fine. 55 s3cmd \ 56 --quiet \ 57 --delete-removed \ 58 --guess-mime-type \ 59 --no-mime-magic \ 60 --acl-public \ 61 --recursive \ 62 --add-header="Cache-Control: max-age=14400" \ 63 --add-header="x-amz-meta-surrogate-control: max-age=31536000, stale-white-revalidate=86400, stale-if-error=604800" \ 64 --add-header="x-amz-meta-surrogate-key: site-$PROJECT" \ 65 sync "$DIR/build/" "s3://hc-sites/$PROJECT/latest/" 66 67 # The s3cmd guessed mime type for text files is often wrong. This is 68 # problematic for some assets, so force their mime types to be correct. 69 echo "Overriding javascript mime-types..." 70 s3cmd \ 71 --mime-type="application/javascript" \ 72 --add-header="Cache-Control: max-age=31536000" \ 73 --exclude "*" \ 74 --include "*.js" \ 75 --recursive \ 76 modify "s3://hc-sites/$PROJECT/latest/" 77 78 echo "Overriding css mime-types..." 79 s3cmd \ 80 --mime-type="text/css" \ 81 --add-header="Cache-Control: max-age=31536000" \ 82 --exclude "*" \ 83 --include "*.css" \ 84 --recursive \ 85 modify "s3://hc-sites/$PROJECT/latest/" 86 87 echo "Overriding svg mime-types..." 88 s3cmd \ 89 --mime-type="image/svg+xml" \ 90 --add-header="Cache-Control: max-age=31536000" \ 91 --exclude "*" \ 92 --include "*.svg" \ 93 --recursive \ 94 modify "s3://hc-sites/$PROJECT/latest/" 95 fi 96 97 # Add redirects if they exist 98 if [ -z "$NO_REDIRECTS" ] || [ ! test -f "./redirects.txt" ]; then 99 echo "Adding redirects..." 100 fields=() 101 while read -r line; do 102 [[ "$line" =~ ^#.* ]] && continue 103 [[ -z "$line" ]] && continue 104 105 # Read fields 106 IFS=" " read -ra parts <<<"$line" 107 fields+=("${parts[@]}") 108 done < "./redirects.txt" 109 110 # Check we have pairs 111 if [ $((${#fields[@]} % 2)) -ne 0 ]; then 112 echo "Bad redirects (not an even number)!" 113 exit 1 114 fi 115 116 # Check we don't have more than 1000 entries (yes, it says 2000 below, but that 117 # is because we've split into multiple lines). 118 if [ "${#fields}" -gt 2000 ]; then 119 echo "More than 1000 entries!" 120 exit 1 121 fi 122 123 # Validations 124 for field in "${fields[@]}"; do 125 if [ "${#field}" -gt 256 ]; then 126 echo "'$field' is > 256 characters!" 127 exit 1 128 fi 129 130 if [ "${field:0:1}" != "/" ]; then 131 echo "'$field' does not start with /!" 132 exit 1 133 fi 134 done 135 136 # Build the payload for single-request updates. 137 jq_args=() 138 jq_query="." 139 for (( i=0; i<${#fields[@]}; i+=2 )); do 140 original="${fields[i]}" 141 redirect="${fields[i+1]}" 142 echo "Redirecting ${original} -> ${redirect}" 143 jq_args+=(--arg "key$((i/2))" "${original}") 144 jq_args+=(--arg "value$((i/2))" "${redirect}") 145 jq_query+="| .items |= (. + [{op: \"upsert\", item_key: \$key$((i/2)), item_value: \$value$((i/2))}])" 146 done 147 148 # Do not post empty items (the API gets sad) 149 if [ "${#jq_args[@]}" -ne 0 ]; then 150 json="$(jq "${jq_args[@]}" "${jq_query}" <<<'{"items": []}')" 151 152 # Post the JSON body 153 curl \ 154 --request "PATCH" \ 155 --header "Fastly-Key: $FASTLY_API_KEY" \ 156 --header "Content-type: application/json" \ 157 --header "Accept: application/json" \ 158 --data "$json"\ 159 "https://api.fastly.com/service/$FASTLY_SERVICE_ID/dictionary/$FASTLY_DICTIONARY_ID/items" 160 fi 161 fi 162 163 # Perform a purge of the surrogate key. 164 if [ -z "$NO_PURGE" ]; then 165 echo "Purging Fastly cache..." 166 curl \ 167 --request "POST" \ 168 --header "Accept: application/json" \ 169 --header "Fastly-Key: $FASTLY_API_KEY" \ 170 --header "Fastly-Soft-Purge: 1" \ 171 "https://api.fastly.com/service/$FASTLY_SERVICE_ID/purge/site-$PROJECT" 172 fi 173 174 # Warm the cache with recursive wget. 175 if [ -z "$NO_WARM" ]; then 176 echo "Warming Fastly cache..." 177 echo "" 178 echo "If this step fails, there are likely missing or broken assets or links" 179 echo "on the website. Run the following command manually on your laptop, and" 180 echo "search for \"ERROR\" in the output:" 181 echo "" 182 echo "wget --recursive --delete-after https://$PROJECT_URL/" 183 echo "" 184 wget \ 185 --delete-after \ 186 --level inf \ 187 --no-directories \ 188 --no-host-directories \ 189 --no-verbose \ 190 --page-requisites \ 191 --recursive \ 192 --spider \ 193 "https://$PROJECT_URL/" 194 fi