Skip to content

Commit 0088068

Browse files
committed
chore: add manual trigger to PyPI publish workflow for RC testing
- Add workflow_dispatch trigger to allow manual publishing - Support publishing from any branch (e.g., complete-refactor for RC) - Enables testing release candidates without merging to main - Workflow respects branch input for checkout - Fixed YAML linting issues (trailing spaces, line length) This allows publishing 1.0.0-rc3 for user testing before merging to main.
1 parent b6c02fa commit 0088068

File tree

3 files changed

+283
-0
lines changed

3 files changed

+283
-0
lines changed

.github/workflows/sdk-publish.yml

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
---
2+
name: Publish to PyPI
3+
4+
# Trigger on push to main when version file changes OR manual trigger
5+
on:
6+
push:
7+
branches:
8+
- main
9+
paths:
10+
- 'src/honeyhive/__init__.py'
11+
workflow_dispatch:
12+
inputs:
13+
branch:
14+
description: 'Branch to publish from (e.g., complete-refactor for RC testing)'
15+
required: false
16+
default: 'main'
17+
18+
permissions:
19+
contents: write # For creating GitHub releases
20+
id-token: write # For trusted publishing to PyPI
21+
22+
env:
23+
PYTHON_VERSION: "3.11"
24+
25+
jobs:
26+
publish:
27+
name: 📦 Build and Publish to PyPI
28+
runs-on: ubuntu-latest
29+
30+
steps:
31+
- name: Checkout code
32+
uses: actions/checkout@v4
33+
with:
34+
ref: ${{ github.event.inputs.branch || github.ref }}
35+
fetch-depth: 0 # Full history for proper release notes
36+
37+
- name: Set up Python
38+
uses: actions/setup-python@v5
39+
with:
40+
python-version: ${{ env.PYTHON_VERSION }}
41+
42+
- name: Install build dependencies
43+
run: |
44+
python -m pip install --upgrade pip
45+
pip install build twine hatchling jq
46+
47+
# === VERSION VALIDATION ===
48+
49+
- name: Extract version from __init__.py
50+
id: get_version
51+
run: |
52+
# Extract version from source
53+
version=$(python -c "exec(open('src/honeyhive/__init__.py').read()); print(__version__)")
54+
echo "version=$version" >> $GITHUB_OUTPUT
55+
echo "📦 Detected version: $version"
56+
57+
# Validate version format (basic check)
58+
if ! echo "$version" | grep -E '^[0-9]+\.[0-9]+\.[0-9]+(rc[0-9]+|alpha[0-9]+|beta[0-9]+)?$'; then
59+
echo "❌ Invalid version format: $version"
60+
echo "Expected format: X.Y.Z or X.Y.Zrc# or X.Y.Zalpha# or X.Y.Zbeta#"
61+
exit 1
62+
fi
63+
64+
echo "✅ Version format is valid"
65+
66+
- name: Check if version already published to PyPI
67+
id: check_pypi
68+
run: |
69+
VERSION="${{ steps.get_version.outputs.version }}"
70+
echo "🔍 Checking if version $VERSION exists on PyPI..."
71+
72+
# Query PyPI API for package versions
73+
response=$(curl -s https://pypi.org/pypi/honeyhive/json || echo '{}')
74+
75+
# Check if version exists in releases
76+
if echo "$response" | python -c \
77+
"import sys, json; \
78+
data = json.load(sys.stdin); \
79+
sys.exit(0 if '$VERSION' in data.get('releases', {}) else 1)"; then
80+
echo "exists=true" >> $GITHUB_OUTPUT
81+
echo "✅ Version $VERSION already published to PyPI"
82+
echo "SKIP_REASON=Version $VERSION already exists on PyPI" >> $GITHUB_OUTPUT
83+
else
84+
echo "exists=false" >> $GITHUB_OUTPUT
85+
echo "🆕 Version $VERSION is new - will publish to PyPI"
86+
fi
87+
88+
- name: Skip publishing (version already exists)
89+
if: steps.check_pypi.outputs.exists == 'true'
90+
run: |
91+
echo "## ✅ Version Already Published" >> $GITHUB_STEP_SUMMARY
92+
echo "" >> $GITHUB_STEP_SUMMARY
93+
echo "**Version:** \`${{ steps.get_version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
94+
echo "" >> $GITHUB_STEP_SUMMARY
95+
echo "This version is already available on PyPI." >> $GITHUB_STEP_SUMMARY
96+
echo "No action needed." >> $GITHUB_STEP_SUMMARY
97+
echo "" >> $GITHUB_STEP_SUMMARY
98+
VERSION="${{ steps.get_version.outputs.version }}"
99+
echo "🔗 [View on PyPI](https://pypi.org/project/honeyhive/$VERSION/)" \
100+
>> $GITHUB_STEP_SUMMARY
101+
102+
echo "✅ Workflow complete - version already published"
103+
exit 0
104+
105+
# === BUILD AND PUBLISH (only if version is new) ===
106+
107+
- name: Verify CHANGELOG updated
108+
if: steps.check_pypi.outputs.exists == 'false'
109+
run: |
110+
VERSION="${{ steps.get_version.outputs.version }}"
111+
112+
if ! grep -q "$VERSION" CHANGELOG.md; then
113+
echo "⚠️ Warning: Version $VERSION not found in CHANGELOG.md"
114+
echo "Please update CHANGELOG.md before releasing"
115+
echo ""
116+
echo "This is a warning only - publishing will continue"
117+
else
118+
echo "✅ CHANGELOG.md contains entry for version $VERSION"
119+
fi
120+
121+
- name: Build distribution packages
122+
if: steps.check_pypi.outputs.exists == 'false'
123+
run: |
124+
echo "📦 Building source distribution and wheel..."
125+
python -m build
126+
127+
echo "📋 Package contents:"
128+
ls -lh dist/
129+
130+
- name: Verify package integrity
131+
if: steps.check_pypi.outputs.exists == 'false'
132+
run: |
133+
echo "🔍 Checking package integrity..."
134+
python -m twine check dist/*
135+
echo "✅ Package integrity verified"
136+
137+
- name: Test package installation
138+
if: steps.check_pypi.outputs.exists == 'false'
139+
run: |
140+
echo "🧪 Testing package installation..."
141+
142+
# Create clean test environment
143+
python -m venv test-install
144+
source test-install/bin/activate
145+
146+
# Install the wheel
147+
pip install dist/*.whl
148+
149+
# Test imports
150+
python -c "
151+
import honeyhive
152+
from honeyhive import HoneyHive, HoneyHiveTracer
153+
from honeyhive import trace, evaluate
154+
155+
print(f'✅ Package installation successful')
156+
print(f'HoneyHive version: {honeyhive.__version__}')
157+
158+
# Verify version matches
159+
expected_version = '${{ steps.get_version.outputs.version }}'
160+
if honeyhive.__version__ != expected_version:
161+
print(f'❌ Version mismatch: {honeyhive.__version__} != {expected_version}')
162+
exit(1)
163+
164+
print(f'✅ Version verified: {honeyhive.__version__}')
165+
"
166+
167+
deactivate
168+
echo "✅ Installation test passed"
169+
170+
- name: Publish to PyPI
171+
if: steps.check_pypi.outputs.exists == 'false'
172+
env:
173+
TWINE_USERNAME: __token__
174+
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
175+
run: |
176+
echo "🚀 Publishing version ${{ steps.get_version.outputs.version }} to PyPI..."
177+
python -m twine upload dist/*
178+
echo "✅ Published to PyPI successfully!"
179+
180+
- name: Verify publication
181+
if: steps.check_pypi.outputs.exists == 'false'
182+
run: |
183+
VERSION="${{ steps.get_version.outputs.version }}"
184+
185+
echo "⏳ Waiting 30 seconds for PyPI to update..."
186+
sleep 30
187+
188+
echo "🔍 Verifying package is available on PyPI..."
189+
max_attempts=5
190+
attempt=1
191+
192+
while [ $attempt -le $max_attempts ]; do
193+
if pip index versions honeyhive | grep -q "$VERSION"; then
194+
echo "✅ Package verified on PyPI!"
195+
echo "🔗 https://pypi.org/project/honeyhive/$VERSION/"
196+
exit 0
197+
fi
198+
199+
echo "Attempt $attempt/$max_attempts: Not yet available, waiting..."
200+
sleep 10
201+
attempt=$((attempt + 1))
202+
done
203+
204+
echo "⚠️ Could not verify package on PyPI within timeout"
205+
echo "This may be a PyPI indexing delay - check manually"
206+
echo "🔗 https://pypi.org/project/honeyhive/$VERSION/"
207+
208+
# === GITHUB RELEASE ===
209+
210+
- name: Create GitHub Release
211+
if: steps.check_pypi.outputs.exists == 'false'
212+
uses: actions/create-release@v1
213+
env:
214+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
215+
with:
216+
tag_name: v${{ steps.get_version.outputs.version }}
217+
release_name: v${{ steps.get_version.outputs.version }}
218+
body: |
219+
# HoneyHive Python SDK v${{ steps.get_version.outputs.version }}
220+
221+
## 📦 Installation
222+
223+
```bash
224+
pip install honeyhive==${{ steps.get_version.outputs.version }}
225+
```
226+
227+
## 🔗 Links
228+
229+
- [PyPI Package](https://pypi.org/project/honeyhive/${{ steps.get_version.outputs.version }}/)
230+
- [Documentation](https://honeyhiveai.github.io/python-sdk/)
231+
- [Changelog](https://github.com/honeyhiveai/python-sdk/blob/main/CHANGELOG.md)
232+
233+
## 📝 Release Notes
234+
235+
See [CHANGELOG.md](https://github.com/honeyhiveai/python-sdk/blob/main/CHANGELOG.md) for detailed changes.
236+
draft: false
237+
prerelease: >-
238+
${{ contains(steps.get_version.outputs.version, 'rc') ||
239+
contains(steps.get_version.outputs.version, 'alpha') ||
240+
contains(steps.get_version.outputs.version, 'beta') }}
241+
242+
# === SUMMARY ===
243+
244+
- name: Generate release summary
245+
if: steps.check_pypi.outputs.exists == 'false'
246+
run: |
247+
echo "# 🚀 Release Published Successfully" >> $GITHUB_STEP_SUMMARY
248+
echo "" >> $GITHUB_STEP_SUMMARY
249+
echo "**Version:** \`${{ steps.get_version.outputs.version }}\`" >> $GITHUB_STEP_SUMMARY
250+
echo "**Published:** $(date -u)" >> $GITHUB_STEP_SUMMARY
251+
echo "" >> $GITHUB_STEP_SUMMARY
252+
VERSION="${{ steps.get_version.outputs.version }}"
253+
echo "## 📦 Installation" >> $GITHUB_STEP_SUMMARY
254+
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
255+
echo "pip install honeyhive==$VERSION" >> $GITHUB_STEP_SUMMARY
256+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
257+
echo "" >> $GITHUB_STEP_SUMMARY
258+
echo "## 🔗 Links" >> $GITHUB_STEP_SUMMARY
259+
echo "- [PyPI Package](https://pypi.org/project/honeyhive/$VERSION/)" \
260+
>> $GITHUB_STEP_SUMMARY
261+
echo "- [GitHub Release]\
262+
(https://github.com/honeyhiveai/python-sdk/releases/tag/v$VERSION)" \
263+
>> $GITHUB_STEP_SUMMARY
264+
echo "- [Documentation](https://honeyhiveai.github.io/python-sdk/)" >> $GITHUB_STEP_SUMMARY
265+
echo "" >> $GITHUB_STEP_SUMMARY
266+
echo "## ✅ Verification" >> $GITHUB_STEP_SUMMARY
267+
echo "- ✅ Package built successfully" >> $GITHUB_STEP_SUMMARY
268+
echo "- ✅ Package integrity verified" >> $GITHUB_STEP_SUMMARY
269+
echo "- ✅ Installation test passed" >> $GITHUB_STEP_SUMMARY
270+
echo "- ✅ Published to PyPI" >> $GITHUB_STEP_SUMMARY
271+
echo "- ✅ GitHub release created" >> $GITHUB_STEP_SUMMARY

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
### Changed
44
- **Version 1.0.0-rc3**: Bumped from 0.1.0-rc3 to reflect stable API
5+
- **🔧 Infrastructure: PyPI Publishing Workflow Enhancement**
6+
- Added manual trigger (`workflow_dispatch`) to PyPI publish workflow
7+
- Enables publishing release candidates from any branch without merging to main
8+
- Supports testing RC versions (e.g., 1.0.0-rc3) before final release
9+
- Workflow validates version, checks PyPI for duplicates, and creates GitHub releases
510
- **📚 Documentation: AWS Strands Integration Updates**
611
- Updated model access documentation to reflect current AWS Bedrock policies (automatic access, no manual request)
712
- Replaced deprecated Claude 3 model IDs with current Claude 4.5 series

docs/changelog.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ Latest Release Notes
1717
Current Version Highlights
1818
~~~~~~~~~~~~~~~~~~~~~~~~~~
1919

20+
**🔧 NEW: Manual PyPI Publishing for Release Candidates (Nov 6, 2025)**
21+
22+
* **Manual Trigger**: Added workflow_dispatch to PyPI publishing workflow
23+
* **RC Testing**: Can now publish release candidates (e.g., 1.0.0-rc3) from any branch
24+
* **Pre-Merge Testing**: Enables user testing of RCs before merging to main
25+
* **Automated**: Still performs all validation, integrity checks, and creates GitHub releases
26+
2027
**📚 UPDATED: AWS Strands Documentation with Current Model IDs (Nov 6, 2025)**
2128

2229
* **Version Bump**: Updated to 1.0.0-rc3 to reflect stable API

0 commit comments

Comments
 (0)