Skip to content

Commit a8ae666

Browse files
authored
Refactor Python package release workflow
Updated the workflow to streamline the release process and improve Python setup.
1 parent 645720b commit a8ae666

File tree

1 file changed

+38
-173
lines changed

1 file changed

+38
-173
lines changed
Lines changed: 38 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -1,203 +1,68 @@
1-
name: Build, validate & Release
2-
3-
# Usage:
4-
# - For PRs: this workflow runs automatically to validate the package builds and installs correctly on multiple Python versions. No artifacts are published for PRs.
5-
# - For releases: when you push a tag like v1.2.3, this workflow runs the full matrix validation, then builds the release artifacts, and finally publishes to PyPI if all checks pass.
6-
# - For manual re-runs: use "Run workflow" and provide a tag-like value such as v2.0.0rc1.
1+
name: Update pypi release
72

83
on:
9-
workflow_dispatch:
10-
inputs:
11-
release_tag:
12-
description: 'Tag to build/publish (e.g. v1.2.3 or v2.0.0rc1)'
13-
required: true
14-
type: string
15-
# Release pipeline: run only when pushing a version-like tag (e.g. v1.2.3)
16-
# Test pipeline: run tests on main/master pushes & pull requests AND tags.
174
push:
185
tags:
19-
- "v*.*.*"
6+
- 'v*.*.*'
7+
pull_request:
208
branches:
219
- main
2210
- master
23-
24-
# Validation pipeline: run on PRs targeting main/master (no publishing)
25-
pull_request:
26-
branches: [main, master]
27-
types: [opened, edited, synchronize, reopened]
28-
29-
# This workflow only needs to read repo contents
30-
permissions:
31-
contents: read
11+
types:
12+
- labeled
13+
- opened
14+
- edited
15+
- synchronize
16+
- reopened
3217

3318
jobs:
34-
test_matrix:
35-
# PR + tag validation: ensure the project builds and installs on multiple Pythons
36-
name: Test install & smoke (Py ${{ matrix.python-version }})
19+
release:
3720
runs-on: ubuntu-latest
38-
strategy:
39-
# Run all versions even if one fails (helps spot version-specific issues)
40-
fail-fast: false
41-
matrix:
42-
python-version: ["3.10", "3.11", "3.12"]
4321

4422
steps:
45-
- name: Validate manual tag input
46-
if: ${{ github.event_name == 'workflow_dispatch' }}
47-
shell: bash
48-
run: |
49-
case "${{ inputs.release_tag }}" in
50-
v*.*.*)
51-
echo "Manual release tag accepted: ${{ inputs.release_tag }}"
52-
;;
53-
*)
54-
echo "release_tag must look like v1.2.3 (or similar, e.g. v2.0.0rc1)"
55-
exit 1
56-
;;
57-
esac
58-
59-
- name: Checkout sources
60-
uses: actions/checkout@v6
23+
- name: Setup Python
24+
id: setup-python
25+
uses: actions/setup-python@v5
6126
with:
62-
ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/tags/{0}', inputs.release_tag) || github.ref }}
27+
python-version: '3.x'
6328

64-
- name: Set up Python
65-
uses: actions/setup-python@v6
29+
- name: Cache dependencies
30+
id: pip-cache
31+
uses: actions/cache@v4
6632
with:
67-
python-version: ${{ matrix.python-version }}
33+
path: ~/.cache/pip
34+
key: ${{ runner.os }}-pip-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('pyproject.toml', 'requirements.txt', 'setup.cfg', 'setup.py') }}
35+
restore-keys: |
36+
${{ runner.os }}-pip-${{ steps.setup-python.outputs.python-version }}-
37+
${{ runner.os }}-pip-
6838
6939
- name: Install Qt/OpenGL runtime deps (Ubuntu)
7040
run: |
7141
sudo apt-get update
72-
sudo apt-get install -y \
7342
libegl1 \
7443
libgl1 \
7544
libopengl0 \
7645
libxkbcommon-x11-0 \
7746
libxcb-cursor0
78-
79-
# Install packaging toolchain:
80-
# - build: creates wheel + sdist
81-
# - twine: validates metadata and can upload (upload only happens in publish job)
82-
- name: Install build tools
83-
run: python -m pip install -U pip build twine
84-
85-
# Build distributions just to verify packaging config works on this Python
86-
- name: Build (for validation only)
87-
run: python -m build
88-
89-
# Validate dist metadata (README rendering, required fields, etc.)
90-
- name: Twine check
91-
run: python -m twine check dist/*
92-
93-
# Smoke test: install the built wheel and verify the package imports
94-
- name: Install from wheel & smoke test
47+
48+
- name: Install dependencies
9549
run: |
96-
WHEEL=$(ls -1 dist/*.whl | head -n 1)
97-
echo "Using wheel: $WHEEL"
98-
python -m pip install \
99-
--extra-index-url https://download.pytorch.org/whl/cpu \
100-
"deeplabcut-live-gui[pytorch] @ file://$(pwd)/${WHEEL}"
101-
python -c "import dlclivegui; print('Imported dlclivegui OK')"
102-
QT_QPA_PLATFORM=offscreen dlclivegui --help
103-
104-
build_release:
105-
# Tag-only build: produce the "official" release artifacts once matrix passed
106-
name: Build release artifacts
107-
runs-on: ubuntu-latest
108-
needs: test_matrix
109-
# Safety gate: only run for version tags, never for PRs/branches
110-
if: ${{ startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch' }}
111-
112-
steps:
113-
- name: Validate manual tag input
114-
if: ${{ github.event_name == 'workflow_dispatch' }}
115-
shell: bash
116-
run: |
117-
case "${{ inputs.release_tag }}" in
118-
v*.*.*)
119-
echo "Manual release tag accepted: ${{ inputs.release_tag }}"
120-
;;
121-
*)
122-
echo "release_tag must look like v1.2.3 (or similar, e.g. v2.0.0rc1)"
123-
exit 1
124-
;;
125-
esac
126-
# Fetch sources for the tagged revision
127-
- name: Checkout sources
128-
uses: actions/checkout@v6
129-
with:
130-
# For a manual run, we want to check out the commit at the provided tag
131-
ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/tags/{0}', inputs.release_tag) || github.ref }}
132-
133-
# Use a single, modern Python for the canonical release build
134-
- name: Set up Python (release build)
135-
uses: actions/setup-python@v6
136-
with:
137-
python-version: "3.12"
138-
139-
# Install build + validation tooling
140-
- name: Install build tools
141-
run: python -m pip install -U pip build twine
142-
143-
# Produce both sdist and wheel in dist/
144-
- name: Build distributions
145-
run: python -m build
146-
147-
# Re-check metadata on the final artifacts we intend to publish
148-
- name: Twine check
149-
run: python -m twine check dist/*
150-
151-
# Store dist/ outputs so the publish job uploads exactly what we built here
152-
- name: Upload dist artifacts
153-
uses: actions/upload-artifact@v4
154-
with:
155-
name: dist
156-
path: dist/*
157-
158-
publish:
159-
# Tag-only publish: download built artifacts and upload them to PyPI
160-
name: Publish to PyPI (API token)
161-
runs-on: ubuntu-latest
162-
needs: build_release
163-
# Safety gate: only run for version tags
164-
if: ${{ startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch' }}
165-
166-
steps:
167-
# Retrieve the exact distributions produced in build_release
168-
- name: Download dist artifacts
169-
uses: actions/download-artifact@v4
170-
with:
171-
name: dist
172-
path: dist
50+
pip install --upgrade pip
51+
pip install wheel
52+
pip install "packaging>=24.2"
53+
pip install build
54+
pip install twine
17355
174-
# Set up Python (only needed to run Twine)
175-
- name: Set up Python (publish)
176-
uses: actions/setup-python@v6
177-
with:
178-
python-version: "3.12"
56+
- name: Checkout code
57+
uses: actions/checkout@v4
17958

180-
# Install twine for uploading
181-
- name: Install Twine
182-
run: python -m pip install -U twine
183-
184-
# Check that the PyPI API token is present before attempting upload (fails fast if not set)
185-
- name: Check PyPI credential presence
186-
shell: bash
187-
env:
188-
TWINE_PASSWORD: ${{ secrets.TWINE_API_KEY }}
189-
run: |
190-
if [ -z "$TWINE_PASSWORD" ]; then
191-
echo "TWINE_PASSWORD is empty"
192-
exit 1
193-
else
194-
echo "TWINE_PASSWORD is present"
195-
fi
196-
197-
# Upload to PyPI using an API token stored in repo secrets.
198-
# --skip-existing avoids failing if you re-run a workflow for the same version.
199-
- name: Publish to PyPI
59+
- name: Build and publish to PyPI
60+
if: ${{ github.event_name == 'push' }}
20061
env:
20162
TWINE_USERNAME: __token__
20263
TWINE_PASSWORD: ${{ secrets.TWINE_API_KEY }}
203-
run: python -m twine upload --non-interactive --skip-existing dist/*
64+
run: |
65+
python -m build
66+
ls dist/
67+
tar tvf dist/deeplabcut-live-gui-*.tar.gz
68+
python3 -m twine upload --verbose dist/*

0 commit comments

Comments
 (0)