diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..83ea4f07 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,52 @@ +name: Upload Python Package + +on: + release: + types: [published] + +permissions: + contents: read + +jobs: + release-build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + - uses: actions/setup-python@65d7f2d534ac1bc67fcd62888c5f4f3d2cb2b236 # v4.7.1 + with: + python-version: '3.10' + + - name: Build release distributions + run: ./scripts/pip.sh + + - name: Upload distributions + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + with: + name: release-dists + path: /tmp/mesoprelease-test/ + + pypi-publish: + runs-on: ubuntu-latest + + needs: + - release-build + + permissions: + # IMPORTANT: this permission is mandatory for trusted publishing + id-token: write + + # Dedicated environments with protections for publishing are strongly recommended. + environment: + name: pypi + url: https://pypi.org/p/mesop + + steps: + - name: Retrieve release distributions + uses: actions/download-artifact@cc203385981b70ca67e1cc392babf9cc229d5806 # v4.1.9 + with: + name: release-dists + path: dist/ + + - name: Publish release distributions to PyPI + uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4 diff --git a/docs/internal/publishing.md b/docs/internal/publishing.md index 9951efe9..9cb2f699 100644 --- a/docs/internal/publishing.md +++ b/docs/internal/publishing.md @@ -2,15 +2,14 @@ Follow these instructions for releasing a new version of Mesop publicly via PyPI (e.g. `pip install mesop`). -If you haven't done this before, follow the [first-time setup](#first-time-upload-setup). - ## Check main branch Before, cutting a release, you'll want to check two things: 1. The `main` branch should be healthy (e.g. latest commit is green). 2. Check the [snyk dashboard](https://app.snyk.io/org/wwwillchen/project/756c376f-d2e7-44f8-9c20-e4062fdf543f) to review security issues: - - It only runs weekly so you need to click "Retest now". If there's any High security issues for a core Mesop file (e.g. anything in `mesop/*`), then you should address it before publishing a release. + + - It only runs weekly so you need to click "Retest now". If there's any High security issues for a core Mesop file (e.g. anything in `mesop/*`), then you should address it before publishing a release. ## Update version to RC @@ -20,53 +19,41 @@ You want to first create an RC (release candidate) to ensure that it works. For example, if the current version is: `0.7.0`, then you should increment the version to `0.8.0rc1` which will create an RC, which is treated as a [pre-release by PyPI](https://packaging.python.org/en/latest/specifications/version-specifiers/#pre-releases). -## Install locally +Merge the PR that bumps the version and then go to the next step to publish a GitHub release which will in turn publish to PyPI. -From the workspace root, run the following command: +## Publish GitHub release -```sh -source ./scripts/pip.sh -``` +After you've submitted the PR which bumps the version and then [publish a GitHub release](https://github.com/google/mesop/releases/new). -This will build the Mesop pip package and install it locally so you can test it. +1. Click "Choose a tag" and type in the version you just released. This will create a new Git tag. +1. Click "Generate release notes". +1. **If this is a an RC:** Click "Set as a pre-release", **otherwise** leave the "Set as the latest release" checked. +1. If this is a regular (non-RC) release, click "Create a discussion for this release". +1. Click "Publish release". ## Testing locally -> TIP: Double check the Mesop version is expected. It's easy to use the wrong version of Mesop by loading `mesop` or `gunicorn` from a different Python path (i.e. not the venv you just created). +**Pre-requisite:** you will need to [install uv](https://docs.astral.sh/uv/getting-started/installation/) before doing the following steps. ### Dev CLI -The above shell script will tell you to run the following command: +Run the following command but replace `0.1.0rc1` with the version that you just published: ```sh -mesop main.py +uvx mesop==0.1.0rc1 scripts/smoketest_app/main.py ``` -This will start the Mesop dev server and you can test that hot reload works. +This will start the Mesop dev server and you can test that hot reload works. Double-check that the version shown is the version that you just released. ### Gunicorn integration -```sh -gunicorn main:me -``` - -> Note: `gunicorn` should already be installed by the shell script above. - -## Upload to PyPI - -If the testing above looks good, then continue with uploading to PyPI. +Run the following command but replace `0.1.0rc1` with the version that you just published: ```sh -rm -rf /tmp/mesoprelease-test/venv-twine \ -&& virtualenv --python python3 /tmp/mesoprelease-test/venv-twine \ -&& source /tmp/mesoprelease-test/venv-twine/bin/activate \ -&& pip install --upgrade pip \ -&& pip install twine \ -&& cd /tmp/mesoprelease-test \ -&& twine upload mesop*.whl +cd scripts/smoketest_app/ && uvx --with mesop==0.1.0rc1 gunicorn@latest main:me ``` -Visit [https://pypi.org/project/mesop/](https://pypi.org/project/mesop/) to see that the new version has been published. +This will launch Mesop under the Gunicorn server so you can make sure it works as expected. ## Test on Colab @@ -90,25 +77,4 @@ If all the testing looks good, then you can update [`mesop/version.py`](https:// `0.8.0rc1` -> `0.8.0` -Re-do the steps above to build, test and upload it to PyPI. - -## Publish GitHub release - -After you've uploaded a new regular release to PyPI, submit the PR which bumps the version and then [publish a GitHub release](https://github.com/google/mesop/releases/new). - -1. Click "Choose a tag" and type in the version you just released. This will create a new Git tag. -1. Click "Genereate release notes". -1. Click "Create a discussion for this release". -1. Click "Publish release". - -## First-time upload setup - -Create a file `~/.pypirc`: - -```yaml -[pypi] - username = __token__ - password = {{password}} -``` - -You will need to get a PyPI token generated by one of the project maintainers. +Re-do the steps above to publish and test the release.