Skip to content

Commit f669e50

Browse files
committed
add python-labs actions
1 parent 9ad9393 commit f669e50

File tree

5 files changed

+279
-0
lines changed

5 files changed

+279
-0
lines changed

README.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,4 +355,77 @@ post-publish:
355355
product_name: winkerberos
356356
token: ${{ github.token }}
357357
dry_run: ${{ inputs.dry_run }}
358+
```
359+
360+
## Python Labs Helper Scripts
361+
362+
These scripts are opinionated helper scripts for Python releases in MongoDB Labs.
363+
364+
### Pre-Publish
365+
366+
Create a new tag. Verify the tag.
367+
Push the commit and tag to the source branch unless `dry_run` is set.
368+
369+
```yaml
370+
- name: Setup
371+
uses: mongodb-labs/drivers-github-tools/setup@v2
372+
with:
373+
...
374+
375+
- uses: mongodb-labs/drivers-github-tools/python-labs/pre-publishv2
376+
with:
377+
version_bump_script: ./.github/scripts/bump-version.sh
378+
dry_run: ${{ inputs.dry_run }}
379+
```
380+
381+
### Post-publish
382+
383+
To be run after separately publishing the [Python package](https://github.com/pypa/gh-action-pypi-publish#trusted-publishing).
384+
Handles follow-up tasks related to publishing Python packages.
385+
It will push the following (dev) version to the source branch.
386+
It will create a draft GitHub release with generated release notes.
387+
If `dry_run` is set, nothing will be pushed.
388+
389+
The jobs should look something like:
390+
391+
```yaml
392+
publish:
393+
name: Upload release to PyPI
394+
runs-on: ubuntu-latest
395+
environment: release
396+
permissions:
397+
id-token: write
398+
steps:
399+
- name: Download all the dists
400+
uses: actions/download-artifact@v4
401+
with:
402+
name: all-dist-${{ github.run_id }}
403+
path: dist/
404+
- name: Publish package distributions to PyPI
405+
if: inputs.dry_run == 'false'
406+
uses: pypa/gh-action-pypi-publish@release/v1
407+
408+
post-publish:
409+
needs: [publish]
410+
name: Handle post-publish actions
411+
runs-on: ubuntu-latest
412+
environment: release
413+
permissions:
414+
id-token: write
415+
contents: write
416+
attestations: write
417+
security-events: write
418+
steps:
419+
- name: Setup
420+
uses: mongodb-labs/drivers-github-tools/setup@v2
421+
with:
422+
...
423+
424+
- uses: mongodb-labs/drivers-github-tools/python-labs/post-publish@v2
425+
with:
426+
following_version: ${{ inputs.following_version }}
427+
version_bump_script: ./.github/scripts/bump-version.sh
428+
product_name: python-bsonjs
429+
token: ${{ github.token }}
430+
dry_run: ${{ inputs.dry_run }}
358431
```
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
2+
name: Python Labs Post-Publish
3+
description: Perform post-release operations for Python Libraries in MongoDB Labs
4+
inputs:
5+
following_version:
6+
description: The following (dev) version
7+
required: false
8+
product_name:
9+
description: The name of the product
10+
required: true
11+
version_bump_script:
12+
description: The version bump script
13+
default: hatch version
14+
working_directory:
15+
description: The working directory for the action
16+
default: "."
17+
tag_template:
18+
description: The template for the git tag
19+
default: "${VERSION}"
20+
repository-url:
21+
description: The PyPI repository URL to use
22+
default: https://upload.pypi.org/legacy/
23+
token:
24+
description: The GitHub access token
25+
dry_run:
26+
description: Whether this is a dry run
27+
required: true
28+
29+
runs:
30+
using: composite
31+
steps:
32+
- uses: actions/setup-python@v5
33+
with:
34+
python-version: '3.11'
35+
- name: Install hatch
36+
shell: bash
37+
run: pipx install hatch
38+
- name: Download all the dists
39+
uses: actions/download-artifact@v4
40+
with:
41+
name: all-dist-${{ github.run_id }}
42+
path: dist/
43+
- name: Get the package version
44+
shell: bash
45+
run: |
46+
# Handle version already bumped
47+
if [ -z "$VERSION" ]; then
48+
# Extract the version from the sdist name, which must be of the form
49+
# {name}-{version}.tar.gz according to PEP 625.
50+
VERSION=$(ls dist/*.tar.gz | rev | cut -d'-' -f 1 | rev | sed 's/.tar.gz//g')
51+
echo "VERSION=$VERSION" >> $GITHUB_ENV
52+
else
53+
echo "VERSION=$VERSION" >> $GITHUB_ENV
54+
fi
55+
- name: Run GitHub Publish script
56+
shell: bash
57+
id: publish-script
58+
run: ${{ github.action_path }}/post-publish.sh
59+
env:
60+
GH_TOKEN: ${{ inputs.token }}
61+
VERSION: ${{ env.VERSION }}
62+
TAG_TEMPLATE: ${{ inputs.tag_template }}
63+
PRODUCT_NAME: ${{ inputs.product_name }}
64+
DRY_RUN: ${{ inputs.dry_run }}
65+
FOLLOWING_VERSION: ${{ inputs.following_version }}
66+
- name: Ensure a clean repo
67+
shell: bash
68+
run: |
69+
git clean -dffx
70+
git pull origin ${GITHUB_REF}
71+
- name: Set following version
72+
uses: mongodb-labs/drivers-github-tools/bump-version@v2
73+
if: inputs.dry_run == 'false'
74+
with:
75+
version: ${{ steps.publish-script.outputs.following_version }}
76+
version_bump_script: ${{ inputs.version_bump_script }}
77+
working_directory: ${{ inputs.working_directory }}
78+
- name: Skip Setting following version
79+
shell: bash
80+
if: inputs.dry_run == 'true'
81+
run: |
82+
echo "Dry run, not setting the following version: ${{ steps.publish-script.outputs.following_version }}" >> $GITHUB_STEP_SUMMARY
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import sys
2+
from packaging.version import Version
3+
4+
version = Version(sys.argv[1])
5+
new_version = None
6+
7+
if version.is_devrelease:
8+
# For dev releases, increment the dev release number.
9+
new_version = f"{version.major}.{version.minor}.{version.micro}.dev{version.dev + 1}"
10+
elif version.is_prerelease:
11+
# For pre releases, go back to dev release.
12+
rel_type, rel_num = version.pre
13+
new_version = f"{version.major}.{version.minor}.{version.micro}.{rel_type}{rel_num + 1}"
14+
elif version.micro == 0:
15+
# For minor releases, go to next minor release.
16+
new_version = f"{version.major}.{version.minor + 1}.0.dev0"
17+
else:
18+
# For patch releases, go to the next patch release.
19+
new_version = f"{version.major}.{version.minor}.{version.micro + 1}.dev0"
20+
21+
print(str(new_version))
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
3+
set -eux
4+
5+
# Handle the following version.
6+
if [ -z "${FOLLOWING_VERSION}" ]; then
7+
pip install packaging
8+
pushd $GITHUB_ACTION_PATH
9+
FOLLOWING_VERSION=$(python handle_following_version.py $VERSION)
10+
popd
11+
fi
12+
echo "following_version=$FOLLOWING_VERSION" >> $GITHUB_OUTPUT
13+
14+
if [ "$DRY_RUN" == "false" ]; then
15+
PUSH_CHANGES=true
16+
echo "Creating draft release with attached files"
17+
TITLE="${PRODUCT_NAME} ${VERSION}"
18+
TAG=$(echo "${TAG_TEMPLATE}" | envsubst)
19+
gh release create ${TAG} --draft --verify-tag --title "${TITLE}" --generate-notes
20+
gh release upload ${TAG} $RELEASE_ASSETS/*.*
21+
JSON="url,tagName,assets,author,createdAt"
22+
JQ='.url,.tagName,.author.login,.createdAt,.assets[].name'
23+
echo "\## $TITLE" >> $GITHUB_STEP_SUMMARY
24+
gh release view --json $JSON --jq $JQ ${TAG} >> $GITHUB_STEP_SUMMARY
25+
else
26+
echo "Dry run, not creating GitHub Release" >> $GITHUB_STEP_SUMMARY
27+
ls -ltr $RELEASE_ASSETS
28+
PUSH_CHANGES=false
29+
fi
30+
31+
# Handle push_changes output.
32+
echo "push_changes=$PUSH_CHANGES" >> $GITHUB_OUTPUT

python-labs/pre-publish/action.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Python Labs Pre-Publish
2+
description: Perform pre-release operations for Python Libraries in MongoDB Labs
3+
inputs:
4+
tag_template:
5+
description: The template for the git tag
6+
default: "${VERSION}"
7+
tag_message_template:
8+
description: The template for the git tag message
9+
default: "Release ${VERSION}"
10+
working_directory:
11+
description: The working directory for the action
12+
default: "."
13+
dry_run:
14+
description: Whether this is a dry run
15+
required: true
16+
17+
outputs:
18+
version:
19+
description: The output version to use
20+
value: ${{ steps.version.outputs.version }}
21+
22+
runs:
23+
using: composite
24+
steps:
25+
- uses: actions/setup-python@v5
26+
with:
27+
python-version: '3.11'
28+
- name: Install hatch
29+
shell: bash
30+
working-directory: ${{ inputs.working_directory }}
31+
run: |
32+
pipx install hatch
33+
pip install build
34+
- name: Handle inputs
35+
shell: bash
36+
env:
37+
DRY_RUN: "${{ inputs.dry_run }}"
38+
run: |
39+
set -eux
40+
# Handle DRY_RUN
41+
if [ "$DRY_RUN" != "true" ]; then
42+
export PUSH_CHANGES=true
43+
else
44+
export PUSH_CHANGES=false
45+
fi
46+
echo "PUSH_CHANGES=$PUSH_CHANGES" >> $GITHUB_ENV
47+
# Handle version
48+
# Extract the version from the sdist name, which must be of the form
49+
# {name}-{version}.tar.gz according to PEP 625.
50+
python -m build --sdist .
51+
VERSION=$(ls dist/*.tar.gz | rev | cut -d'-' -f 1 | rev | sed 's/.tar.gz//g')
52+
echo "VERSION=$VERSION" >> $GITHUB_ENV
53+
rm -rf dist
54+
- name: Tag version
55+
uses: mongodb-labs/drivers-github-tools/tag-version@v2
56+
with:
57+
version: ${{ env.VERSION }}
58+
tag_template: ${{ inputs.tag_template }}
59+
tag_message_template: ${{ inputs.tag_message_template }}
60+
push_tag: ${{ env.PUSH_CHANGES }}
61+
- name: Handle version output
62+
shell: bash
63+
id: version
64+
run: |
65+
if [ "${{ inputs.dry_run}}" == 'true' ]; then
66+
echo "version=${{ github.ref }}" >> $GITHUB_OUTPUT
67+
else
68+
export VERSION=${{ env.VERSION }}
69+
export TAG=$(echo "${{ inputs.tag_template }}" | envsubst)
70+
echo "version=$TAG" >> $GITHUB_OUTPUT
71+
fi

0 commit comments

Comments
 (0)