Add a convenience utility for publishing
diff --git a/README.md b/README.md
index c7c8797..67924ab 100644
--- a/README.md
+++ b/README.md
@@ -144,7 +144,11 @@
 git push upstream upstream/asf-staging:asf-site
 ```
 
-Note that Step 3 should always be a fast-forward merge. That is, there should
+A convenience script can be found that performs these steps for you, after
+asking which remote you want to use. It is located in the `main` branch at
+`_devtools/publish.sh`
+
+Note that Step 2 should always be a fast-forward merge. That is, there should
 never be any reason to force-push it if everything is done correctly. If extra
 commits are ever added to `asf-site` that are not present in `asf-staging`,
 then those branches will need to be sync'd back up in order to continue
diff --git a/_devtools/publish.sh b/_devtools/publish.sh
new file mode 100755
index 0000000..d1df990
--- /dev/null
+++ b/_devtools/publish.sh
@@ -0,0 +1,36 @@
+#! /usr/bin/env bash
+
+# catch most errors
+set -eE
+trap 'echo "[ERROR] Error occurred at $BASH_SOURCE:$LINENO command: $BASH_COMMAND"' ERR
+
+function publish_main() {
+  local src='asf-staging' dst='asf-site' r yn remotes=()
+  for r in $(git remote); do
+    remotes+=("$r ($(git config "remote.$r.url"))")
+  done
+  echo 'Select a remote:'
+  select r in "${remotes[@]}"; do
+    if [[ -n $r ]]; then
+      r="${r%% *}"
+      git remote update --prune "${r:?}"
+      echo 'Updating would perform the following (if anything):'
+      git push --dry-run "$r" "$r/$src:refs/heads/$dst"
+      if [[ "$(git rev-parse "remotes/$r/$src")" == "$(git rev-parse "remotes/$r/$dst")" ]]; then
+        return 0
+      fi
+      read -r -p "Are you sure you want to publish '$r/$src' to '$r/$dst'? " yn
+      if [[ $yn =~ ^[yY]$|^[yY][eE][sS]$ ]]; then
+        git push "$r" "$r/$src:refs/heads/$dst"
+      else
+        echo "You did not answer 'y' or 'yes', so no updates were made."
+      fi
+      return 0
+    else
+      echo 'ERROR - Invalid selection'
+      return 1
+    fi
+  done
+}
+
+publish_main "$@" || exit 1