Skip to content

Commit 4c70dc5

Browse files
Create automatic workflow for DSPy release (#181)
1 parent 204f8e3 commit 4c70dc5

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
name: Build and Release databricks-dspy
2+
3+
on:
4+
push:
5+
tags:
6+
- 'databricks-dspy-v*'
7+
8+
jobs:
9+
extract_tag:
10+
runs-on: ubuntu-latest
11+
outputs:
12+
version: ${{ steps.extract.outputs.version }}
13+
steps:
14+
- name: Extract version from tag
15+
id: extract
16+
run: |
17+
# Extract version from tag like databricks-dspy-v1.0.0 -> 1.0.0
18+
TAG=${GITHUB_REF#refs/tags/databricks-dspy-v}
19+
echo "version=$TAG" >> $GITHUB_OUTPUT
20+
echo "Extracted version: $TAG"
21+
22+
build_and_test:
23+
runs-on: ubuntu-latest
24+
needs: extract_tag
25+
defaults:
26+
run:
27+
working-directory: integrations/dspy
28+
steps:
29+
- name: Checkout code
30+
uses: actions/checkout@v4
31+
32+
- name: Set up Python
33+
uses: actions/setup-python@v5
34+
with:
35+
python-version: "3.12"
36+
37+
- name: Install dependencies
38+
run: |
39+
python -m pip install --upgrade pip
40+
pip install build twine
41+
pip install .[dev]
42+
43+
- name: Lint with ruff
44+
run: |
45+
ruff check .
46+
ruff format --check .
47+
48+
- name: Run tests
49+
run: |
50+
pytest tests/unit_tests
51+
52+
- name: Validate version matches tag
53+
run: |
54+
PYPROJECT_VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
55+
TAG_VERSION="${{ needs.extract_tag.outputs.version }}"
56+
if [ "$PYPROJECT_VERSION" != "$TAG_VERSION" ]; then
57+
echo "Error: Version in pyproject.toml ($PYPROJECT_VERSION) does not match tag ($TAG_VERSION)"
58+
exit 1
59+
fi
60+
echo "Version validation passed: $PYPROJECT_VERSION"
61+
62+
- name: Build original package for PyPI
63+
run: |
64+
python -m build
65+
# Save original package for PyPI
66+
mkdir -p dist-pypi
67+
cp dist/* dist-pypi/
68+
69+
- name: Build test package for TestPyPI
70+
run: |
71+
# Clean previous build
72+
rm -rf dist/*
73+
# Update package name for TestPyPI
74+
sed -i 's/^name *= *".*"/name = "databricks-dspy-test"/' pyproject.toml
75+
# Add dev suffix with timestamp for unique TestPyPI versions
76+
TIMESTAMP=$(date +%Y%m%d%H%M%S)
77+
sed -i "s/^version *= *\"\(.*\)\"/version = \"\1.dev${TIMESTAMP}\"/" pyproject.toml
78+
echo "Updated version for TestPyPI: $(grep '^version = ' pyproject.toml)"
79+
# Build test package
80+
python -m build
81+
82+
- name: Check packages
83+
run: |
84+
twine check dist/*
85+
twine check dist-pypi/*
86+
87+
- name: Upload TestPyPI artifacts
88+
uses: actions/upload-artifact@v4
89+
with:
90+
name: dist-test-files
91+
path: integrations/dspy/dist/
92+
93+
- name: Upload PyPI artifacts
94+
uses: actions/upload-artifact@v4
95+
with:
96+
name: dist-pypi-files
97+
path: integrations/dspy/dist-pypi/
98+
99+
publish_test_pypi:
100+
runs-on: ubuntu-latest
101+
needs: [extract_tag, build_and_test]
102+
defaults:
103+
run:
104+
working-directory: integrations/dspy
105+
environment:
106+
name: test-pypi
107+
url: https://test.pypi.org/p/databricks-dspy-test
108+
permissions:
109+
id-token: write
110+
steps:
111+
- name: Checkout code
112+
uses: actions/checkout@v4
113+
114+
- name: Set up Python
115+
uses: actions/setup-python@v5
116+
with:
117+
python-version: "3.12"
118+
119+
- name: Download TestPyPI artifacts
120+
uses: actions/download-artifact@v4
121+
with:
122+
name: dist-test-files
123+
path: integrations/dspy/dist/
124+
125+
- name: Install twine
126+
run: |
127+
python -m pip install --upgrade pip twine
128+
129+
- name: Publish to TestPyPI
130+
uses: pypa/gh-action-pypi-publish@release/v1
131+
with:
132+
repository-url: https://test.pypi.org/legacy/
133+
packages-dir: integrations/dspy/dist/
134+
135+
- name: Test installation from TestPyPI
136+
run: |
137+
sleep 30 # Wait for package to be available
138+
# Install the test package with dev version
139+
pip install --index-url https://test.pypi.org/simple/ \
140+
--extra-index-url https://pypi.org/simple \
141+
databricks-dspy-test
142+
python -c "import databricks_dspy; print('Package installed successfully from TestPyPI')"
143+
144+
publish_pypi:
145+
runs-on: ubuntu-latest
146+
if: github.repository_owner == 'databricks'
147+
needs: [extract_tag, publish_test_pypi]
148+
defaults:
149+
run:
150+
working-directory: integrations/dspy
151+
environment:
152+
name: pypi
153+
url: https://pypi.org/p/databricks-dspy
154+
permissions:
155+
id-token: write
156+
steps:
157+
- name: Checkout code
158+
uses: actions/checkout@v4
159+
160+
- name: Set up Python
161+
uses: actions/setup-python@v5
162+
with:
163+
python-version: "3.12"
164+
165+
- name: Download PyPI artifacts
166+
uses: actions/download-artifact@v4
167+
with:
168+
name: dist-pypi-files
169+
path: integrations/dspy/dist/
170+
171+
- name: Install twine
172+
run: |
173+
python -m pip install --upgrade pip twine
174+
175+
- name: Publish to PyPI
176+
uses: pypa/gh-action-pypi-publish@release/v1
177+
with:
178+
packages-dir: integrations/dspy/dist/
179+
180+
- name: Test installation from PyPI
181+
run: |
182+
sleep 60 # Wait for package to be available
183+
pip install databricks-dspy==${{ needs.extract_tag.outputs.version }}
184+
python -c "import databricks_dspy; print('Package installed successfully from PyPI')"

0 commit comments

Comments
 (0)