github.com/web-platform-tests/wpt.fyi@v0.0.0-20240530210107-70cf978996f1/util/deploy-production.sh (about)

     1  #!/bin/bash
     2  
     3  # Helper script for deploying to production.
     4  # Needs the following packages to be installed: google-cloud-cli, gh, jq
     5  
     6  #set -x #echo on for debugging purposes
     7  set -e
     8  
     9  usage() {
    10    USAGE="Usage: deploy-production.sh [-f] [-b]
    11      -b : skip GitHub issue creation
    12      -f : Always deploy (even if checks have failed)"
    13    echo "${USAGE}"
    14  }
    15  
    16  # Deletes the service passed as a parameter.
    17  delete_oldest_version() {
    18    OLDEST_REV=$(gcloud app --project=wptdashboard versions list --sort-by=last_deployed_time --filter="service=$1" --limit=1 --format=json | jq -r '.[] | .id')
    19    echo "Deleting $1 service version $OLDEST_REV"
    20    if confirm "Delete $1 service version $OLDEST_REV?"; then
    21      gcloud app versions delete --service=$SERVICE $OLDEST_REV
    22    else
    23      echo "Skipping $1 service version $OLDEST_REV"
    24    fi
    25  }
    26  
    27  while getopts ':bfh' flag; do
    28    case "${flag}" in
    29      b) SKIP_ISSUE_CREATION='true' ;;
    30      f) FORCE_DEPLOY='true' ;;
    31      h|*) usage && exit 0;;
    32    esac
    33  done
    34  
    35  GH_OWNER="web-platform-tests"
    36  GH_REPO="wpt.fyi"
    37  PROD_LABEL="prod"
    38  RELEASE_LABEL="release"
    39  UTIL_DIR=$(dirname $0)
    40  source "${UTIL_DIR}/logging.sh"
    41  source "${UTIL_DIR}/commands.sh"
    42  
    43  if [[ ${SKIP_ISSUE_CREATION} != "true" ]];
    44  then
    45    # Find changes to deploy.
    46    LAST_DEPLOYED_SHA=$(gcloud app --project=wptdashboard versions list --hide-no-traffic --filter='service=default' --format=yaml | grep id | head -1 | cut -d' ' -f2 | sed 's/rev-//')
    47    CHANGELIST=$(git log $LAST_DEPLOYED_SHA..HEAD --oneline)
    48    if [[ "${CHANGELIST}" == ""  ]];
    49    then
    50        echo "No new changes to deploy."
    51        exit 0
    52    fi
    53    CHANGE_COUNT=$(echo "$CHANGELIST"|wc -l)
    54    echo -e "There are $CHANGE_COUNT changes to deploy:\n$CHANGELIST"
    55  
    56    # Verfiy that all commit checks passed.
    57    FAILED_CHECKS=$(gh api /repos/"$GH_OWNER"/"$GH_REPO"/commits/HEAD/check-runs | jq -r '.check_runs | map(select(.conclusion == "failure"))')
    58    FAILURES=$(echo "$FAILED_CHECKS" | jq -r 'length')
    59    if [[ "${FAILURES}" != "0"  ]];
    60    then
    61        echo -e "\n$FAILURES checks failed for the latest commit:"
    62        echo "$FAILED_CHECKS" | jq -r '.[] | .name + ": " + .html_url'
    63        if [[ "${FORCE_DEPLOY}" != "true" ]];
    64        then
    65            echo -e "\nVisit the link(s) above and if failed checks should not block deployment, run the script again with -f"
    66            exit 1
    67        fi
    68    fi
    69  
    70    # File a deployment bug.
    71    NEW_SHA=$(git rev-parse --short HEAD)
    72    LAST_DEPLOYMENT_ISSUE=$(gh issue list --state closed --label "$PROD_LABEL" --label "$RELEASE_LABEL" --limit 1 --json number --jq '.[] | .number')
    73    BUG_TITLE="Deploy $NEW_SHA to production"
    74    BUG_BODY=$(cat << EOF
    75  Previous deployment was #$LAST_DEPLOYMENT_ISSUE ($LAST_DEPLOYED_SHA)
    76  
    77  Changelist $LAST_DEPLOYED_SHA...$NEW_SHA
    78  
    79  Changes:
    80  $CHANGELIST
    81  
    82  This push is happening as part of the regular weekly push.
    83  
    84  Pushing all three services - webapp, processor, and searchcache.
    85  EOF
    86  )
    87  
    88    gh issue create --title "$BUG_TITLE" --body "$BUG_BODY" --label "$PROD_LABEL" --label "$RELEASE_LABEL"
    89    if [[ $? != 0 ]];
    90    then
    91        echo "GitHub issue creation failed"
    92        exit 2
    93    fi
    94  fi
    95  
    96  # Confirm there are 3 versions for each service and delete the oldest version.
    97  SERVICES="default processor searchcache"
    98  for SERVICE in $SERVICES
    99  do
   100    VERSIONS=$(gcloud app --project=wptdashboard versions list --filter="service=$SERVICE" --format=list | wc -l)
   101    if [[ "${VERSIONS}" -eq "3"  ]];
   102    then
   103      echo "Found 3 versions for service $SERVICE, will delete the oldest"
   104      delete_oldest_version $SERVICE
   105    elif [[ "${VERSIONS}" -lt "3"  ]];
   106    then
   107      echo -e "\n$VERSIONS versions found for service $SERVICE"
   108    else
   109      echo -e "\n$VERSIONS versions found for service $SERVICE!"
   110      exit 3
   111    fi
   112  done
   113  
   114  # Start a docker instance.
   115  ${UTIL_DIR}/docker-dev/run.sh -d
   116  # Login to gcloud if not already logged in.
   117  wptd_exec_it gcloud auth login
   118  # Deploy the services.
   119  wptd_exec_it make deploy_production PROJECT=wptdashboard APP_PATH=webapp/web
   120  wptd_exec_it make deploy_production PROJECT=wptdashboard APP_PATH=results-processor
   121  wptd_exec_it make deploy_production PROJECT=wptdashboard APP_PATH=api/query/cache/service
   122  cd webapp/web
   123  gcloud app deploy --project=wptdashboard index.yaml queue.yaml dispatch.yaml
   124  cd ../..
   125  
   126  # Stop docker.
   127  ${UTIL_DIR}/docker-dev/run.sh -s
   128  
   129  # Confirm that everything works as expected and redirect traffic.
   130  VERSION_URL=$(gcloud app --project=wptdashboard versions list --sort-by=~last_deployed_time --filter='service=default' --limit=1 --format=json | jq -r '.[] | .version.versionUrl')
   131  LATEST_VERSION=$(gcloud app --project=wptdashboard versions list --sort-by=~last_deployed_time --filter='service=default' --limit=1 --format=json | jq -r '.[] | .id')
   132  MESSAGE="Visit $VERSION_URL to confirm that everything works (page load, search, test expansion, show history). Redirect traffic now?"
   133  if confirm "$MESSAGE"; then
   134    for SERVICE in $SERVICES
   135    do
   136      gcloud app services set-traffic $SERVICE --splits $LATEST_VERSION=1
   137    done
   138  else
   139    echo "Don't forget to migrate traffic to the new version."
   140  fi
   141  
   142  # Update and close deployment bug.
   143  LAST_DEPLOYMENT_ISSUE=$(gh issue list --state open --label "$PROD_LABEL" --label "$RELEASE_LABEL" --limit 1 --json number --jq '.[] | .number')
   144  gh issue close "$LAST_DEPLOYMENT_ISSUE" -c "Deployment is now complete."