Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(tsmith/automate-release): release cryoet-data-portal-python-client 3.1.0 #985

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
38c76b4
fix: add link to documentation to pypi
Bento007 Jul 31, 2024
d7e5446
chore: prepare client for release automation
Bento007 Jul 31, 2024
95d4f0e
chore: prepare client for release automation
Bento007 Jul 31, 2024
508516b
chore: automate pypi release
Bento007 Jul 31, 2024
e3dbab0
add extra label
Bento007 Jul 31, 2024
e7f306c
Merge branch 'main' into tsmith/automate-release
Bento007 Jul 31, 2024
898ca30
remove extra label
Bento007 Jul 31, 2024
4ed9147
Merge remote-tracking branch 'origin/tsmith/automate-release' into ts…
Bento007 Jul 31, 2024
85342ee
need release please
Bento007 Jul 31, 2024
c858079
point at pypi
Bento007 Jul 31, 2024
b2debe9
remove todos
Bento007 Jul 31, 2024
8fcc103
update release_process.md for release-please
Bento007 Jul 31, 2024
1ff4275
add pypi package url
Bento007 Aug 1, 2024
0620320
Merge branch 'main' into tsmith/automate-release
Bento007 Aug 1, 2024
9813cec
Consolidate release please runs
Bento007 Aug 1, 2024
4d1e19c
test release-please PR runs tests
Bento007 Aug 2, 2024
370f01d
test release-please PR runs tests
Bento007 Aug 2, 2024
fb5f38e
test release-please PR runs tests
Bento007 Aug 2, 2024
59c8297
Add check that python test client passed
Bento007 Aug 2, 2024
51d1040
Add check that python test client passed
Bento007 Aug 2, 2024
378a9b1
Add check that python test client passed
Bento007 Aug 2, 2024
39d5718
Add check that python test client passed
Bento007 Aug 2, 2024
6f73e27
Add check that python test client passed
Bento007 Aug 2, 2024
ffc240d
Merge branch 'refs/heads/main' into tsmith/automate-release
Bento007 Aug 20, 2024
2498634
chore(tsmith/automate-release): release cryoet-data-portal-python-cli…
github-actions[bot] Aug 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 0 additions & 32 deletions .github/workflows/create-frontend-release-pr.yml

This file was deleted.

37 changes: 0 additions & 37 deletions .github/workflows/py-build.yml

This file was deleted.

34 changes: 34 additions & 0 deletions .github/workflows/release-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# write a Github actions to verify the workflow "Python Client Tests" on the main branch ran successfully.
name: Client Release Check
on:
pull_request:
branches:
- release-please--branches--tsmith/automate-release--components--cryoet-data-portal-python-client
- tsmith/automate-release
push:
branches:
- release-please--branches--tsmith/automate-release--components--cryoet-data-portal-python-client
- tsmith/automate-release

jobs:
release-check:
runs-on: ubuntu-latest
steps:
- name: check client tests on main
uses: actions/github-script@v7
with:
retries: 10
script: |
const { data } = await github.rest.checks.listForRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: 'main',
check_name: 'Python Client Tests',
filter: 'latest',
});
if (data.total_count === 0) {
core.setFailed('No checks found on main');
}
if (data.check_runs[0].conclusion !== 'success') {
core.setFailed('Python Client Tests on main did not pass');
}
62 changes: 62 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Create Release PRs

on:
workflow_dispatch:
push:
branches:
- main
- tsmith/automate-release

permissions:
contents: write
pull-requests: write

jobs:
release-please:
concurrency:
group: release-prs-${{ github.ref }}
cancel-in-progress: true

runs-on: ubuntu-latest
steps:
- name: release please
uses: googleapis/release-please-action@v4
id: release
with:
# TODO Configuring using manifest file as workaround until we move the frontend to its own repo
manifest-file: "release-please.manifest.json"
config-file: "release-please.config.json"
target-branch: "tsmith/automate-release"

outputs:
paths_released: ${{ steps.release.outputs.paths_released }}

publish-pypi-package:
name: Build and publish Python package to PyPI
runs-on: ubuntu-latest
needs: release-please
if: contains(needs.release-please.outputs.paths_released, 'client/python/cryoet_data_portal')
environment:
name: pypi
url: https://pypi.org/p/cryoet-data-portal
permissions:
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
steps:
- name: Checkout ref branch
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
fetch-depth: 0

- uses: actions/setup-python@v4
with:
pyton-version: "3.10"

- name: build
run: |
make build -C client/python/cryoet_data_portal

- name: Publish distribution πŸ“¦ to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: client/python/cryoet_data_portal/dist
22 changes: 22 additions & 0 deletions client/python/cryoet_data_portal/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Changelog

## [3.1.0](https://github.com/chanzuckerberg/cryoet-data-portal/compare/cryoet-data-portal-python-client-v3.0.3...cryoet-data-portal-python-client-v3.1.0) (2024-08-20)


### ✨ Features

* add user agent to client requests ([#966](https://github.com/chanzuckerberg/cryoet-data-portal/issues/966)) ([8209cd4](https://github.com/chanzuckerberg/cryoet-data-portal/commit/8209cd46cb8ab21341c7ee94672db3bae78f9aa2))


### 🐞 Bug Fixes

* add link to documentation to pypi ([38c76b4](https://github.com/chanzuckerberg/cryoet-data-portal/commit/38c76b450294d35a276d102ed816b12dd810ee99))
* create recursive_from_prefix path if it does not exist ([#940](https://github.com/chanzuckerberg/cryoet-data-portal/issues/940)) ([0069f08](https://github.com/chanzuckerberg/cryoet-data-portal/commit/0069f080987ac05efef82d024cb17f4dc307a0f3))
* Use match with substring for exception check in client tests ([#895](https://github.com/chanzuckerberg/cryoet-data-portal/issues/895)) ([07352ec](https://github.com/chanzuckerberg/cryoet-data-portal/commit/07352ecdb8c6f50ffe97ff7be9777c0cf6dd66cb))


### 🧹 Miscellaneous Chores

* Add additional test case to TestGetDestinationPath ([#955](https://github.com/chanzuckerberg/cryoet-data-portal/issues/955)) ([a9412a8](https://github.com/chanzuckerberg/cryoet-data-portal/commit/a9412a80f3b24ff94b0803fdd59d3583b4521706))
* automate pypi release ([508516b](https://github.com/chanzuckerberg/cryoet-data-portal/commit/508516b956b14d6aa18c8f39b5c28938f0b49220))
* prepare client for release automation ([d7e5446](https://github.com/chanzuckerberg/cryoet-data-portal/commit/d7e5446519aebfbc180eaef98a11ce65ec7d49dc))
6 changes: 6 additions & 0 deletions client/python/cryoet_data_portal/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ test:
export BOTO_ENDPOINT_URL=http://localhost:4000; \
export BOTO_SIGNATURE_VERSION=s3v4; \
pytest -vvv -s . $(TEST)

.PHONY: build
build:
python -m pip install --upgrade pip
pip install build twine
python -m build
5 changes: 3 additions & 2 deletions client/python/cryoet_data_portal/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[build-system]
requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"]
requires = ["setuptools>=64"]
build-backend = "setuptools.build_meta"

[project]
name = "cryoet_data_portal"
dynamic = ["version"]
version = "3.1.0"
description = "API Client to facilitate the use of the CryoET Portal. For more information about the API and the project visit https://github.com/chanzuckerberg/cryoet-data-portal/"
authors = [
{ name = "Chan Zuckerberg Initiative", email = "cryoetdataportal@chanzuckerberg.com" }
Expand Down Expand Up @@ -38,6 +38,7 @@ dependencies= [
[project.urls]
homepage = "https://github.com/chanzuckerberg/cryoet-data-portal"
repository = "https://github.com/chanzuckerberg/cryoet-data-portal"
documentation = "https://chanzuckerberg.github.io/cryoet-data-portal/python-api.html"

[tool.setuptools.packages.find]
where = ["src"]
Expand Down
109 changes: 7 additions & 102 deletions client/python/cryoet_data_portal/release_process.md
Original file line number Diff line number Diff line change
@@ -1,105 +1,10 @@
# Python package release process
To release a new version of python client, merge a pull request to main with change to **./client/python/cryoet-data-portal**. Release-please will automatically create a PR with the a version bump if needed. The name of the PR will be **chore(main): release cryoet-data-portal-python-client vX.X.X**. Here is an [example](https://github.com/chanzuckerberg/cryoet-data-portal/pull/981) of a release PR. Merging the release-please PR will create a new release in github and a new version will be uploaded to pypi. If no changes were made that affect the python client, the python client will not be release. Closing the PR will skip the release of these changes and they will be included in the next release.

The following approach is used to manage releases of the Python package:
If the version number needs to be change see [release-plesae documentation](https://github.com/googleapis/release-please?tab=readme-ov-file#how-do-i-change-the-version-number) for how to change the version number. This same process can be used to manually release the package.

1. The package is automatically built (sdist and wheels) in a GitHub action, and build artifacts are uploaded to GitHub.
2. Release candidate testing is done by installing built assets from Github.
3. Build versions are managed via [`setuptools_scm`](https://github.com/pypa/setuptools_scm) and the version is automatically determined from git tags.
4. Releases are created and managed via GitHub Releases, leaving a tag in place from which future branches (eg, emergency fixes) can be created.
5. Built packages are published to PyPi _from_ the GitHub assets, i.e. are never hand-created, to reduce errors.

## Prerequisites

While not strictly required, this process assumes you have met the following prerequisites:

- You have write access to the `chanzuckerberg/cryoet-data-portal` repo
- You have an account on pypi.org and test.pypi.org, both with access to the cryoet-data-portal project
- You have the Github CLI tool (`gh`) installed. See [documentation](https://cli.github.com/).
- You have the `pipx` CLI tool installed. See [documentation](https://pypa.github.io/pipx/).

## Step 1: Building the package assets

A build will occur automatically upon each commit to main, upon each commit to a PR, or when the build workflow is manually invoked. The build workflow is defined by the GH `py-build.yml` workflow. Build artifacts are the Python setuptools-created `sdist` and `wheel`, and are retained for a limited period of time (currently the GH default of 90 days).

Unless you are revising and testing the build process itself, there is no need to manually perform a build.

## Step 2: Release candidate testing

Any pre-built asset on Github can be installed and tested from the Github URL. For example:

1. Identify the GH workflow run ID that contains the asset you wish to test. A simple way to do this is:
```shell
$ gh run list
```
Alternatively, you can use the "Actions" tag in the GitHub web UI.
2. Download the build artifact.zip from GitHub, using the GH Action run ID associated with the `build` action for your commit OR utilizing the web UI:

```shell
$ gh run download <ID>
```

If you download using the browser, unzip into a temp directory, e.g.,

```shell
$ unzip artifact.zip -d ./artifact/
Archive: artifact.zip
inflating: ./artifact/cryoet-data-portal-0.0.1.dev0-py3-none-any.whl
inflating: ./artifact/cryoet-data-portal-0.0.1.dev0.tar.gz
```

3. Install and test the downloaded build, e.g.,
```shell
$ pip uninstall cryoet-data-portal
$ pip install ./artifact/cryoet-data-portal-*-any.whl
```

To test a release candidate:

1. Identify the build you wish to test. Download and test the artifact built for that commit as described above.
2. Perform end-user testing, using the above installation method
3. If acceptable, proceed to Step 3 - create a release.

If testing exposes problems, fix and commit a solution as you would any other change.

## Step 3: Create a release

Prior to this process, determine the correct semver version number for the new release. Please consider if this is a major, minor or patch release, and if it should have a tag (e.g., an alpha build, with a `a#` suffix or a pre-release candidate, with a `-rc` suffix). If you are not sure, please review [PEP 440](https://peps.python.org/pep-0440/) for more information.

This process also assumes you are releasing from `main`. If you create a release PR, it should be merged to main before releasing.

To create a release, perform the following:

1. Identify both the (tested & validated) commit and semver for the release.
2. Tag the commit with the release version (_including_ a `v` prefix) and push the tag to origin. **Important**: use an annotated tag, e.g., `git tag -a v1.9.4 -m 'Release 1.9.4`. For example (please replace <SEMVER> with your version, _including_ a `v`, e.g. `v1.9.4`:
```shell
$ git tag -a <SEMVER> -m 'Release <SEMVER>'
$ git push origin <SEMVER>
```
3. Trigger a build for this tag by manually triggering the `py-build.yml` workflow. For example:
```shell
$ gh workflow run py-build.yml --ref <SEMVER>
```
4. When the workflow completes, make note of the run ID (e.g., using `gh run list`).
5. Optional, _but recommended_: download the asset from the build workflow and validate it.
6. Create and publish a GitHub Release, using the `<SEMVER>` tag above (e.g., `v1.9.4`). It is recommended that you include a release summary and change log in the GH release.

## Step 4: Publish assets to PyPi

To publish built release assets to PyPi (_note_: this will require your pypi/testpypi login):

1. Download the assets built for your release commit, using the same method as step 2 above, e.g.,
```shell
$ gh run download <ID>
```
2. Optional: upload to TestPyPi (this assumes the downloaded assets are in ./artifact/).

```shell
pipx run twine upload --repository testpypi ./artifact/*
```

Following the upload, confirm correct presentation on the project page and ability to download install from TestPyPi. To test with TestPyPi, use `pipx run twine upload --repository testpypi ./artifact/*`. You can find more information [here](https://packaging.python.org/en/latest/guides/using-testpypi/).

3. Use twine to upload to PyPi (this assumes the downloaded assets are in ./artifact/), e.g.,
```shell
pipx run twine upload ./artifact/*
```
## Build Locally
The python client can be build locally by running the following:
```bash
make build
```
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
TomogramAuthor,
TomogramVoxelSpacing,
)
from ._version import version

__version__ = version
__version__ = "3.1.0"

__all__ = [
"Client",
Expand Down
11 changes: 8 additions & 3 deletions release-please.config.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
{
"bootstrap-sha": "79825da91dd20c3be2f47912285e2c977848af32",
"skip-github-release": true,
"changelog-sections": [
{ "type": "feat", "section": "✨ Features" },
{ "type": "fix", "section": "🐞 Bug Fixes" },
Expand All @@ -16,7 +14,14 @@
],
"packages": {
"frontend": {
"release-type": "node"
"release-type": "node",
"skip-github-release": true,
"separate-pull-requests": true
},
"client/python/cryoet_data_portal": {
"package-name": "cryoet-data-portal-python-client",
"release-type": "python",
"separate-pull-requests": true
}
}
}
3 changes: 2 additions & 1 deletion release-please.manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"frontend": "1.22.0"
"frontend": "1.22.0",
"client/python/cryoet_data_portal": "3.1.0"
}