-
Notifications
You must be signed in to change notification settings - Fork 0
225 lines (199 loc) · 8.58 KB
/
publish-pypi.yml
File metadata and controls
225 lines (199 loc) · 8.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# This workflow is triggered when a tag is pushed or a GitHub release is created.
# It can also be run manually to re-publish to PyPI in case it failed for some reason.
# You can run this workflow by navigating to https://www.github.com/hanzoai/python-sdk/actions/workflows/publish-pypi.yml
name: Publish PyPI
on:
workflow_dispatch:
inputs:
packages:
description: 'Packages to publish (space-separated, or "all" for everything)'
required: false
default: 'all'
push:
tags:
- 'v*'
- 'hanzo-*'
- 'hanzoai-*'
- 'hanzo-tools-*'
release:
types: [published]
jobs:
# Run tests first to ensure code quality
test:
name: Run Tests
uses: ./.github/workflows/test.yml
publish-all-packages:
name: Publish All Python Packages
runs-on: ubuntu-latest
needs: test # Only publish if tests pass
if: always() && !cancelled()
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all tags
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install build tools
run: |
python -m pip install --upgrade pip
pip install build twine
- name: Get tag name
id: get_tag
run: echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
- name: Determine packages to publish
id: determine_packages
run: |
TAG="${{ steps.get_tag.outputs.TAG }}"
MANUAL_INPUT="${{ github.event.inputs.packages }}"
PACKAGES=""
# All hanzo-tools packages
TOOLS_PACKAGES="hanzo-tools-core hanzo-tools-fs hanzo-tools-shell hanzo-tools-browser hanzo-tools-memory hanzo-tools-todo hanzo-tools-reasoning hanzo-tools-lsp hanzo-tools-refactor hanzo-tools-database hanzo-tools-agent hanzo-tools-jupyter hanzo-tools-editor hanzo-tools-llm hanzo-tools-vector hanzo-tools-config hanzo-tools-mcp hanzo-tools-computer hanzo-tools"
# Main packages
MAIN_PACKAGES="hanzoai hanzo hanzo-cli hanzo-kms hanzo-iam hanzo-consensus hanzo-network hanzo-mcp hanzo-memory hanzo-aci hanzo-repl"
# Handle manual workflow dispatch
if [ -n "$MANUAL_INPUT" ]; then
if [ "$MANUAL_INPUT" = "all" ]; then
PACKAGES="$MAIN_PACKAGES $TOOLS_PACKAGES"
else
PACKAGES="$MANUAL_INPUT"
fi
# Handle specific package tags
elif [[ $TAG == hanzo-tools-core-* ]]; then
PACKAGES="hanzo-tools-core"
elif [[ $TAG == hanzo-tools-fs-* ]]; then
PACKAGES="hanzo-tools-fs"
elif [[ $TAG == hanzo-tools-shell-* ]]; then
PACKAGES="hanzo-tools-shell"
elif [[ $TAG == hanzo-tools-browser-* ]]; then
PACKAGES="hanzo-tools-browser"
elif [[ $TAG == hanzo-tools-memory-* ]]; then
PACKAGES="hanzo-tools-memory"
elif [[ $TAG == hanzo-tools-todo-* ]]; then
PACKAGES="hanzo-tools-todo"
elif [[ $TAG == hanzo-tools-reasoning-* ]]; then
PACKAGES="hanzo-tools-reasoning"
elif [[ $TAG == hanzo-tools-lsp-* ]]; then
PACKAGES="hanzo-tools-lsp"
elif [[ $TAG == hanzo-tools-refactor-* ]]; then
PACKAGES="hanzo-tools-refactor"
elif [[ $TAG == hanzo-tools-database-* ]]; then
PACKAGES="hanzo-tools-database"
elif [[ $TAG == hanzo-tools-agent-* ]]; then
PACKAGES="hanzo-tools-agent"
elif [[ $TAG == hanzo-tools-jupyter-* ]]; then
PACKAGES="hanzo-tools-jupyter"
elif [[ $TAG == hanzo-tools-editor-* ]]; then
PACKAGES="hanzo-tools-editor"
elif [[ $TAG == hanzo-tools-llm-* ]]; then
PACKAGES="hanzo-tools-llm"
elif [[ $TAG == hanzo-tools-vector-* ]]; then
PACKAGES="hanzo-tools-vector"
elif [[ $TAG == hanzo-tools-config-* ]]; then
PACKAGES="hanzo-tools-config"
elif [[ $TAG == hanzo-tools-mcp-* ]]; then
PACKAGES="hanzo-tools-mcp"
elif [[ $TAG == hanzo-tools-computer-* ]]; then
PACKAGES="hanzo-tools-computer"
elif [[ $TAG == hanzo-tools-* ]]; then
# All tools packages
PACKAGES="$TOOLS_PACKAGES"
elif [[ $TAG == hanzo-cli-* ]]; then
PACKAGES="hanzo-cli"
elif [[ $TAG == hanzo-kms-* ]]; then
PACKAGES="hanzo-kms"
elif [[ $TAG == hanzo-iam-* ]]; then
PACKAGES="hanzo-iam"
elif [[ $TAG == hanzo-consensus-* ]]; then
PACKAGES="hanzo-consensus"
elif [[ $TAG == hanzo-network-* ]]; then
PACKAGES="hanzo-network"
elif [[ $TAG == hanzo-mcp-* ]]; then
PACKAGES="hanzo-mcp"
elif [[ $TAG == hanzo-memory-* ]]; then
PACKAGES="hanzo-memory"
elif [[ $TAG == hanzo-aci-* ]]; then
PACKAGES="hanzo-aci"
elif [[ $TAG == hanzo-repl-* ]]; then
PACKAGES="hanzo-repl"
elif [[ $TAG == hanzoai-* ]]; then
PACKAGES="hanzoai"
elif [[ $TAG == hanzo-* ]]; then
PACKAGES="hanzo"
elif [[ $TAG == v* ]]; then
# For general version tags, publish all packages
PACKAGES="$MAIN_PACKAGES $TOOLS_PACKAGES"
fi
echo "PACKAGES=$PACKAGES" >> $GITHUB_OUTPUT
echo "Publishing packages: $PACKAGES"
- name: Build and publish packages
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.HANZO_PYPI_TOKEN || secrets.PYPI_TOKEN }}
run: |
PACKAGES="${{ steps.determine_packages.outputs.PACKAGES }}"
if [ -z "$PACKAGES" ]; then
echo "No packages to publish for tag ${{ steps.get_tag.outputs.TAG }}"
exit 0
fi
for package in $PACKAGES; do
echo "=========================================="
echo "Building and publishing $package..."
echo "=========================================="
# hanzoai is the root package, all others live under pkg/
if [ "$package" = "hanzoai" ]; then
PKG_DIR="."
elif [ -d "pkg/$package" ]; then
PKG_DIR="pkg/$package"
else
echo "Warning: Package directory pkg/$package does not exist, skipping"
continue
fi
# Clean any previous builds
rm -rf "$PKG_DIR/dist/" "$PKG_DIR/build/"
# Build from repo root to avoid stdlib shadowing (hanzoai/types vs types)
python -m build "$PKG_DIR" --outdir "$PKG_DIR/dist"
# Upload to PyPI
python -m twine upload "$PKG_DIR/dist/"* --skip-existing || echo "Warning: Failed to upload $package (may already exist)"
done
- name: Create GitHub Release Notes
if: startsWith(github.ref, 'refs/tags/v')
uses: actions/github-script@v7
with:
script: |
const tag = '${{ steps.get_tag.outputs.TAG }}';
const packages = '${{ steps.determine_packages.outputs.PACKAGES }}'.split(' ').filter(p => p);
let body = `## 🚀 Published Python Packages\n\n`;
body += `The following packages have been published to PyPI:\n\n`;
for (const pkg of packages) {
body += `- ✅ **${pkg}** - [View on PyPI](https://pypi.org/project/${pkg}/)\n`;
}
body += `\n### Installation\n\n`;
body += `\`\`\`bash\n`;
body += `# Install main SDK\n`;
body += `pip install hanzo\n\n`;
body += `# Install MCP tools\n`;
body += `pip install hanzo-mcp\n\n`;
body += `# Install individual tool packages\n`;
body += `pip install hanzo-tools # All tools\n`;
body += `pip install hanzo-tools-core # Core only\n`;
body += `\`\`\`\n`;
// Update release if it exists
try {
const releases = await github.rest.repos.listReleases({
owner: context.repo.owner,
repo: context.repo.repo,
});
const release = releases.data.find(r => r.tag_name === tag);
if (release) {
await github.rest.repos.updateRelease({
owner: context.repo.owner,
repo: context.repo.repo,
release_id: release.id,
body: release.body + '\n\n' + body,
});
}
} catch (error) {
console.log('Could not update release notes:', error);
}