THRIFT-5546: automate pypi publishing [ci skip]

When a pre-release is created on GitHub for the repo it will publish
to the TestPyPI service, and if that pre-release is promoted to a
release, it will publish to the PyPI (real) service.
diff --git a/.github/actions/cloudtruth/configure-action b/.github/actions/cloudtruth/configure-action
new file mode 160000
index 0000000..9ec7a0a
--- /dev/null
+++ b/.github/actions/cloudtruth/configure-action
@@ -0,0 +1 @@
+Subproject commit 9ec7a0ab1c6e1bf92620c4a1b3fd38c614dc1659
diff --git a/.github/actions/pypa/gh-action-pypi-publish b/.github/actions/pypa/gh-action-pypi-publish
new file mode 160000
index 0000000..717ba43
--- /dev/null
+++ b/.github/actions/pypa/gh-action-pypi-publish
@@ -0,0 +1 @@
+Subproject commit 717ba43cfbb0387f6ce311b169a825772f54d295
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000..5bc73a0
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,52 @@
+#
+# Apache Thrift release publishing workflow
+#
+# When a release is created in GitHub, it should be created in pre-release
+# mode first.  This will trigger a "prereleased" event which will cause this
+# workflow to run and publish packages to various package managers.  You
+# must check the Actions tab in GitHub to see the result of the workflow.
+#
+# github.event.action is either "prereleased" or "released" and corresponds
+# with a named environment in CloudTruth
+#
+#           |         Destinations
+# Language  | Prereleased   | Released
+# ----------+---------------+---------------
+# py        | test.pypi.org | pypi.org
+#
+---
+name: Publish
+
+on:
+  release:
+    types:
+      - prereleased
+      - released
+
+permissions:
+  contents: read
+
+jobs:
+  pypi:
+    runs-on: ubuntu-latest
+    timeout-minutes: 5
+    steps:
+      - uses: actions/checkout@v3
+        with:
+          persist-credentials: false
+          submodules: recursive
+      - uses: actions/setup-python@v3
+      - name: Get configuration and secrets from CloudTruth
+        uses: ./.github/actions/cloudtruth/configure-action
+        with:
+          apikey: "${{ secrets.CLOUDTRUTH_API_KEY }}"
+          project: "${{ github.repository }}"
+          environment: "${{ github.event.action }}"
+      - name: build sdist
+        run: "cd lib/py && python setup.py sdist"
+      - name: Publish to PyPI
+        uses: ./.github/actions/pypa/gh-action-pypi-publish
+        with:
+          password: "${{ env.PYPI_PASSWORD }}"
+          repository_url: "${{ env.PYPI_REPOSITORY }}"
+          packages_dir: lib/py/dist
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..bbaf357
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule ".github/actions/cloudtruth/configure-action"]
+	path = .github/actions/cloudtruth/configure-action
+	url = https://github.com/cloudtruth/configure-action
+[submodule ".github/actions/pypa/gh-action-pypi-publish"]
+	path = .github/actions/pypa/gh-action-pypi-publish
+	url = https://github.com/pypa/gh-action-pypi-publish
diff --git a/doc/ReleaseManagement.md b/doc/ReleaseManagement.md
index e659ad4..83e07aa 100644
--- a/doc/ReleaseManagement.md
+++ b/doc/ReleaseManagement.md
@@ -333,7 +333,18 @@
 
     **NOTE:** If you get the error "gpg failed to sign the data" when tagging, try this fix: ```export GPG_TTY=$(tty)```. Alternatively, it may be necessary to specify the ```-u <keyid>``` as an additional argument.
 
-1. Create a new release from the [GitHub Tags Page](https://github.com/apache/thrift/tags).  Attach the statically built Windows thrift compiler as a binary here.
+1. Create a new release from the [GitHub Tags Page](https://github.com/apache/thrift/tags).
+
+    Attach the statically built Windows thrift compiler as a binary here.
+
+    You may find it useful to use the button that automates release notes.
+
+    We have *some* automation in place to get packages published to various package managers.  To leverage this:
+    
+    - Please first create a "pre-release" and save.
+    - Then look at the Actions tab and look for the prereleased action.  It will upload packages to package managers that we have automated and support "test" or "staging" modes.
+    - Go check out those packages and make sure they look correct.
+    - Come back to the release page and uncheck the "pre-release" checkbox and save.  This will cause another action to get launched that publishes     packages for real.
 
 1. Merge the release branch into master.  This ensures all changes made to fix up the release are in master.