Skip to content

Commit 63826e1

Browse files
blink1073NoahStapp
andauthored
INTPYTHON-589 Add automated release support for pymongoarrow (#293)
Co-authored-by: Noah Stapp <[email protected]>
1 parent 6df7da9 commit 63826e1

File tree

3 files changed

+237
-148
lines changed

3 files changed

+237
-148
lines changed

.github/workflows/dist-python.yml

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
name: Python Dist
2+
3+
on:
4+
push:
5+
tags:
6+
- "[0-9]+.[0-9]+.[0-9]+"
7+
- "[0-9]+.[0-9]+.[0-9]+.post[0-9]+"
8+
- "[0-9]+.[0-9]+.[0-9]+[a-b][0-9]+"
9+
- "[0-9]+.[0-9]+.[0-9]+rc[0-9]+"
10+
workflow_dispatch:
11+
pull_request:
12+
workflow_call:
13+
inputs:
14+
ref:
15+
required: true
16+
type: string
17+
18+
concurrency:
19+
group: dist-${{ github.ref }}
20+
cancel-in-progress: true
21+
22+
defaults:
23+
run:
24+
working-directory: ./bindings/python
25+
shell: bash -eux {0}
26+
27+
jobs:
28+
build_wheels:
29+
name: Build wheel for ${{ matrix.python }}-${{ matrix.buildplat[1] }}
30+
runs-on: ${{ matrix.buildplat[0] }}
31+
strategy:
32+
# Ensure that a wheel builder finishes even if another fails
33+
fail-fast: false
34+
matrix:
35+
# Github Actions doesn't support pairing matrix values together, let's improvise
36+
# https://github.com/github/feedback/discussions/7835#discussioncomment-1769026
37+
buildplat:
38+
- [ubuntu-24.04, manylinux_x86_64]
39+
- [ubuntu-24.04, manylinux_aarch64]
40+
- [macos-14, macosx_*]
41+
- [windows-2019, win_amd64]
42+
python: ["cp39", "cp310", "cp311", "cp312", "cp313"]
43+
exclude:
44+
- buildplat: [macos-14, macosx_*]
45+
python: "cp39"
46+
include:
47+
- buildplat: [macos-13, macosx_*]
48+
python: "cp39"
49+
50+
steps:
51+
- name: Checkout pymongoarrow
52+
uses: actions/checkout@v4
53+
with:
54+
persist-credentials: false
55+
56+
- name: Set up python version
57+
run: |
58+
export PYTHON_VERSION=$(sed 's/^cp3/3./' <<< ${{ matrix.python }} )
59+
echo "PYTHON_VERSION=$PYTHON_VERSION" >> $GITHUB_ENV
60+
61+
- uses: actions/setup-python@v5
62+
with:
63+
python-version: ${{env.PYTHON_VERSION}}
64+
allow-prereleases: true
65+
66+
- name: Set up QEMU
67+
if: matrix.buildplat[1] == 'manylinux_aarch64'
68+
uses: docker/setup-qemu-action@v3
69+
with:
70+
# setup-qemu-action by default uses `tonistiigi/binfmt:latest` image,
71+
# which is out of date. This causes seg faults during build.
72+
# Here we manually fix the version.
73+
image: tonistiigi/binfmt:qemu-v8.1.5
74+
platforms: arm64
75+
76+
- name: Install pkg-config on MacOS
77+
if: runner.os == 'macOS'
78+
run: brew install pkg-config
79+
80+
- name: Install cibuildwheel
81+
run: python -m pip install "cibuildwheel>=2.4,<3"
82+
83+
- name: Build MacOS Py39 Wheels
84+
if: ${{ matrix.python == 'cp39' && matrix.buildplat[0] == 'macos-11' }}
85+
env:
86+
MACOS_TEST_SKIP: "*arm64"
87+
CIBW_BUILD: cp39-macosx_*
88+
MACOSX_DEPLOYMENT_TARGET: "10.14"
89+
run: python -m cibuildwheel --output-dir wheelhouse
90+
91+
- name: Build wheels
92+
if: ${{ matrix.buildplat[0] != 'macos-11' }}
93+
env:
94+
CIBW_BUILD: ${{ matrix.python }}-${{ matrix.buildplat[1] }}
95+
MACOSX_DEPLOYMENT_TARGET: "12.0"
96+
run: python -m cibuildwheel --output-dir wheelhouse
97+
98+
- uses: actions/upload-artifact@v4
99+
with:
100+
name: ${{ matrix.python }}-${{ startsWith(matrix.buildplat[1], 'macosx') && 'macosx' || matrix.buildplat[1] }}
101+
path: ./bindings/python/wheelhouse/*.whl
102+
if-no-files-found: error
103+
104+
make_sdist:
105+
name: Make SDist
106+
runs-on: macos-latest
107+
steps:
108+
- uses: actions/checkout@v4
109+
with:
110+
persist-credentials: false
111+
112+
- uses: actions/setup-python@v5
113+
with:
114+
# Build sdist on lowest supported Python
115+
python-version: '3.9'
116+
117+
- name: Install tox
118+
run: |
119+
python -m pip install tox
120+
121+
- name: Build SDist
122+
working-directory: ./bindings/python
123+
run: |
124+
set -ex
125+
export LIBBSON_INSTALL_DIR="$(pwd)/libbson"
126+
tox -e build-libbson
127+
tox -e build-dist -- --sdist
128+
129+
- name: Test Sdist
130+
working-directory: ./bindings/python
131+
run: |
132+
export LIBBSON_INSTALL_DIR="$(pwd)/libbson"
133+
python -m pip install dist/*.gz
134+
cd ..
135+
python -c "from pymongoarrow.lib import libbson_version"
136+
137+
- uses: actions/upload-artifact@v4
138+
with:
139+
name: "sdist"
140+
path: ./bindings/python/dist/*.tar.gz
141+
142+
collect_dist:
143+
runs-on: ubuntu-latest
144+
needs: [build_wheels, make_sdist]
145+
name: Download Wheels
146+
steps:
147+
- name: Download all workflow run artifacts
148+
uses: actions/download-artifact@v4
149+
- name: Flatten directory
150+
working-directory: .
151+
run: |
152+
find . -mindepth 2 -type f -exec mv {} . \;
153+
find . -type d -empty -delete
154+
- uses: actions/upload-artifact@v4
155+
with:
156+
name: all-dist-${{ github.run_id }}
157+
path: "./*"

.github/workflows/release-python.yml

Lines changed: 74 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,26 @@
1-
name: Python Wheels
1+
name: Release
22

33
on:
4-
push:
5-
branches: ["main"]
6-
tags:
7-
- "**"
8-
pull_request:
94
workflow_dispatch:
5+
inputs:
6+
following_version:
7+
description: "The post (dev) version to set"
8+
dry_run:
9+
description: "Dry Run?"
10+
default: false
11+
type: boolean
1012
schedule:
1113
- cron: '30 5 * * *'
1214

15+
env:
16+
# Changes per repo
17+
PRODUCT_NAME: PyMongoArrow
18+
# Constant
19+
# inputs will be empty on a scheduled run. so, we only set dry_run
20+
# to 'false' when the input is set to 'false'.
21+
DRY_RUN: ${{ ! contains(inputs.dry_run, 'false') }}
22+
FOLLOWING_VERSION: ${{ inputs.following_version || '' }}
23+
1324
concurrency:
1425
group: wheels-${{ github.ref }}
1526
cancel-in-progress: true
@@ -20,142 +31,51 @@ defaults:
2031
shell: bash -eux {0}
2132

2233
jobs:
23-
build_wheels:
24-
name: Build wheel for ${{ matrix.python }}-${{ matrix.buildplat[1] }}
25-
runs-on: ${{ matrix.buildplat[0] }}
26-
strategy:
27-
# Ensure that a wheel builder finishes even if another fails
28-
fail-fast: false
29-
matrix:
30-
# Github Actions doesn't support pairing matrix values together, let's improvise
31-
# https://github.com/github/feedback/discussions/7835#discussioncomment-1769026
32-
buildplat:
33-
- [ubuntu-24.04, manylinux_x86_64]
34-
- [ubuntu-24.04, manylinux_aarch64]
35-
- [macos-14, macosx_*]
36-
- [windows-2019, win_amd64]
37-
python: ["cp39", "cp310", "cp311", "cp312", "cp313"]
38-
exclude:
39-
- buildplat: [macos-14, macosx_*]
40-
python: "cp39"
41-
include:
42-
- buildplat: [macos-13, macosx_*]
43-
python: "cp39"
44-
45-
steps:
46-
- name: Checkout pymongoarrow
47-
uses: actions/checkout@v4
48-
with:
49-
persist-credentials: false
50-
51-
- name: Set up python version
52-
run: |
53-
export PYTHON_VERSION=$(sed 's/^cp3/3./' <<< ${{ matrix.python }} )
54-
echo "PYTHON_VERSION=$PYTHON_VERSION" >> $GITHUB_ENV
55-
56-
- uses: actions/setup-python@v5
57-
with:
58-
python-version: ${{env.PYTHON_VERSION}}
59-
cache: 'pip'
60-
cache-dependency-path: 'bindings/python/pyproject.toml'
61-
allow-prereleases: true
62-
63-
- name: Set up QEMU
64-
if: matrix.buildplat[1] == 'manylinux_aarch64'
65-
uses: docker/setup-qemu-action@v3
66-
with:
67-
# setup-qemu-action by default uses `tonistiigi/binfmt:latest` image,
68-
# which is out of date. This causes seg faults during build.
69-
# Here we manually fix the version.
70-
image: tonistiigi/binfmt:qemu-v8.1.5
71-
platforms: arm64
72-
73-
- name: Install pkg-config on MacOS
74-
if: runner.os == 'macOS'
75-
run: brew install pkg-config
76-
77-
- name: Install cibuildwheel
78-
run: python -m pip install "cibuildwheel>=2.4,<3"
79-
80-
- name: Build MacOS Py39 Wheels
81-
if: ${{ matrix.python == 'cp39' && matrix.buildplat[0] == 'macos-11' }}
82-
env:
83-
MACOS_TEST_SKIP: "*arm64"
84-
CIBW_BUILD: cp39-macosx_*
85-
MACOSX_DEPLOYMENT_TARGET: "10.14"
86-
run: python -m cibuildwheel --output-dir wheelhouse
87-
88-
- name: Build wheels
89-
if: ${{ matrix.buildplat[0] != 'macos-11' }}
90-
env:
91-
CIBW_BUILD: ${{ matrix.python }}-${{ matrix.buildplat[1] }}
92-
MACOSX_DEPLOYMENT_TARGET: "12.0"
93-
run: python -m cibuildwheel --output-dir wheelhouse
94-
95-
- uses: actions/upload-artifact@v4
96-
with:
97-
name: ${{ matrix.python }}-${{ startsWith(matrix.buildplat[1], 'macosx') && 'macosx' || matrix.buildplat[1] }}
98-
path: ./bindings/python/wheelhouse/*.whl
99-
if-no-files-found: error
100-
101-
make_sdist:
102-
name: Make SDist
103-
runs-on: macos-latest
34+
pre-publish:
35+
environment: release
36+
runs-on: ubuntu-latest
37+
if: github.repository_owner == 'mongodb' || github.event_name == 'workflow_dispatch'
38+
permissions:
39+
id-token: write
40+
contents: write
41+
outputs:
42+
version: ${{ steps.pre-publish.outputs.version }}
10443
steps:
105-
- uses: actions/checkout@v4
44+
- uses: mongodb-labs/drivers-github-tools/secure-checkout@v2
10645
with:
107-
persist-credentials: false
108-
109-
- uses: actions/setup-python@v5
46+
app_id: ${{ vars.APP_ID }}
47+
private_key: ${{ secrets.APP_PRIVATE_KEY }}
48+
- uses: mongodb-labs/drivers-github-tools/setup@v2
11049
with:
111-
# Build sdist on lowest supported Python
112-
python-version: '3.9'
113-
50+
aws_role_arn: ${{ secrets.AWS_ROLE_ARN }}
51+
aws_region_name: ${{ vars.AWS_REGION_NAME }}
52+
aws_secret_id: ${{ secrets.AWS_SECRET_ID }}
53+
artifactory_username: ${{ vars.ARTIFACTORY_USERNAME }}
11454
- name: Install tox
11555
run: |
11656
python -m pip install tox
117-
118-
- name: Build SDist
57+
- name: Build Libbson
11958
working-directory: ./bindings/python
12059
run: |
12160
set -ex
12261
export LIBBSON_INSTALL_DIR="$(pwd)/libbson"
12362
tox -e build-libbson
124-
tox -e build-dist -- --sdist
125-
126-
- name: Test Sdist
127-
working-directory: ./bindings/python
128-
run: |
129-
export LIBBSON_INSTALL_DIR="$(pwd)/libbson"
130-
python -m pip install dist/*.gz
131-
cd ..
132-
python -c "from pymongoarrow.lib import libbson_version"
133-
134-
- uses: actions/upload-artifact@v4
63+
echo "LIBBSON_INSTALL_DIR=$LIBBSON_INSTALL_DIR" >> $GITHUB_ENV
64+
- uses: mongodb-labs/drivers-github-tools/python-labs/pre-publish@v2
65+
id: pre-publish
13566
with:
136-
name: "sdist"
137-
path: ./bindings/python/dist/*.tar.gz
67+
dry_run: ${{ env.DRY_RUN }}
68+
working_directory: ./bindings/python
13869

139-
collect_dist:
140-
runs-on: ubuntu-latest
141-
needs: [build_wheels, make_sdist]
142-
name: Download Wheels
143-
steps:
144-
- name: Download all workflow run artifacts
145-
uses: actions/download-artifact@v4
146-
- name: Flatten directory
147-
working-directory: .
148-
run: |
149-
find . -mindepth 2 -type f -exec mv {} . \;
150-
find . -type d -empty -delete
151-
- uses: actions/upload-artifact@v4
152-
with:
153-
name: all-dist-${{ github.run_id }}
154-
path: "./*"
70+
build-dist:
71+
needs: [pre-publish]
72+
uses: ./.github/workflows/dist-python.yml
73+
with:
74+
ref: ${{ needs.pre-publish.outputs.version }}
15575

15676
publish:
15777
# https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/#publishing-the-distribution-to-pypi
158-
needs: [collect_dist]
78+
needs: [build-dist]
15979
if: (github.repository_owner == 'mongodb-labs' && github.event_name != 'pull_request') || github.event_name == 'workflow_dispatch'
16080
runs-on: ubuntu-latest
16181
environment: release
@@ -176,3 +96,31 @@ jobs:
17696
- name: Publish distribution 📦 to PyPI
17797
if: startsWith(github.ref, 'refs/tags/')
17898
uses: pypa/gh-action-pypi-publish@release/v1
99+
100+
post-publish:
101+
needs: [publish]
102+
runs-on: ubuntu-latest
103+
environment: release
104+
permissions:
105+
id-token: write
106+
contents: write
107+
attestations: write
108+
security-events: write
109+
steps:
110+
- uses: mongodb-labs/drivers-github-tools/secure-checkout@v2
111+
with:
112+
app_id: ${{ vars.APP_ID }}
113+
private_key: ${{ secrets.APP_PRIVATE_KEY }}
114+
- uses: mongodb-labs/drivers-github-tools/setup@v2
115+
with:
116+
aws_role_arn: ${{ secrets.AWS_ROLE_ARN }}
117+
aws_region_name: ${{ vars.AWS_REGION_NAME }}
118+
aws_secret_id: ${{ secrets.AWS_SECRET_ID }}
119+
artifactory_username: ${{ vars.ARTIFACTORY_USERNAME }}
120+
- uses: mongodb-labs/drivers-github-tools/python-labs/post-publish@v2
121+
with:
122+
following_version: ${{ env.FOLLOWING_VERSION }}
123+
product_name: ${{ env.PRODUCT_NAME }}
124+
token: ${{ github.token }}
125+
dry_run: ${{ env.DRY_RUN }}
126+
working_directory: ./bindings/python

0 commit comments

Comments
 (0)