Skip to content

Commit dad8326

Browse files
authored
Merge pull request #13 from awslabs/add-publish-workflow
Add PyPI publish workflow with trusted publishers
2 parents db2b104 + 03beb56 commit dad8326

1 file changed

Lines changed: 153 additions & 0 deletions

File tree

.github/workflows/publish.yml

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
name: Publish to PyPI
2+
3+
on:
4+
push:
5+
tags:
6+
- 'sdk-v*'
7+
- 'agentic-mcp-server-v*'
8+
- 'mcp-server-v*'
9+
- 'mcp-client-v*'
10+
- 'types-v*'
11+
12+
permissions:
13+
contents: write # Required for creating GitHub Releases
14+
id-token: write # Required for trusted publishing (OIDC)
15+
16+
jobs:
17+
resolve-package:
18+
runs-on: ubuntu-latest
19+
outputs:
20+
package-path: ${{ steps.resolve.outputs.package-path }}
21+
package-name: ${{ steps.resolve.outputs.package-name }}
22+
version: ${{ steps.resolve.outputs.version }}
23+
steps:
24+
- uses: actions/checkout@v6
25+
26+
- name: Resolve package from tag
27+
id: resolve
28+
run: |
29+
TAG="${GITHUB_REF#refs/tags/}"
30+
echo "Tag: $TAG"
31+
32+
# Map tag prefix to package directory
33+
if [[ "$TAG" == sdk-v* ]]; then
34+
PACKAGE_PATH="packages/sdk"
35+
elif [[ "$TAG" == agentic-mcp-server-v* ]]; then
36+
PACKAGE_PATH="packages/agentic-mcp-server"
37+
elif [[ "$TAG" == mcp-server-v* ]]; then
38+
PACKAGE_PATH="packages/mcp-server"
39+
elif [[ "$TAG" == mcp-client-v* ]]; then
40+
PACKAGE_PATH="packages/mcp-client"
41+
elif [[ "$TAG" == types-v* ]]; then
42+
PACKAGE_PATH="packages/types"
43+
else
44+
echo "::error::Unknown tag prefix: $TAG"
45+
exit 1
46+
fi
47+
48+
# Extract version from tag (strip prefix up to and including 'v')
49+
TAG_VERSION="${TAG#*-v}"
50+
51+
# Read version from pyproject.toml
52+
PYPROJECT_VERSION=$(python -c "
53+
import tomllib
54+
with open('$PACKAGE_PATH/pyproject.toml', 'rb') as f:
55+
print(tomllib.load(f)['project']['version'])
56+
")
57+
58+
# Verify tag matches pyproject.toml
59+
if [[ "$TAG_VERSION" != "$PYPROJECT_VERSION" ]]; then
60+
echo "::error::Tag version ($TAG_VERSION) does not match pyproject.toml version ($PYPROJECT_VERSION) in $PACKAGE_PATH"
61+
exit 1
62+
fi
63+
64+
PACKAGE_NAME=$(python -c "
65+
import tomllib
66+
with open('$PACKAGE_PATH/pyproject.toml', 'rb') as f:
67+
print(tomllib.load(f)['project']['name'])
68+
")
69+
70+
echo "package-path=$PACKAGE_PATH" >> "$GITHUB_OUTPUT"
71+
echo "package-name=$PACKAGE_NAME" >> "$GITHUB_OUTPUT"
72+
echo "version=$TAG_VERSION" >> "$GITHUB_OUTPUT"
73+
echo "Publishing $PACKAGE_NAME $TAG_VERSION from $PACKAGE_PATH"
74+
75+
test:
76+
needs: resolve-package
77+
uses: ./.github/workflows/_test-package.yml
78+
with:
79+
package-path: ${{ needs.resolve-package.outputs.package-path }}
80+
extra-deps: packages/types packages/mcp-client
81+
82+
build:
83+
needs: [resolve-package, test]
84+
runs-on: ubuntu-latest
85+
outputs:
86+
package-path: ${{ needs.resolve-package.outputs.package-path }}
87+
steps:
88+
- uses: actions/checkout@v6
89+
90+
- name: Set up Python 3.12
91+
uses: actions/setup-python@v5
92+
with:
93+
python-version: "3.12"
94+
95+
- name: Install build tools
96+
run: pip install build
97+
98+
- name: Build package
99+
run: python -m build ${{ needs.resolve-package.outputs.package-path }}
100+
101+
- name: Upload dist artifacts
102+
uses: actions/upload-artifact@v4
103+
with:
104+
name: dist
105+
path: ${{ needs.resolve-package.outputs.package-path }}/dist/
106+
107+
publish:
108+
needs: [resolve-package, build]
109+
runs-on: ubuntu-latest
110+
environment: pypi
111+
steps:
112+
- name: Download dist artifacts
113+
uses: actions/download-artifact@v4
114+
with:
115+
name: dist
116+
path: dist/
117+
118+
- name: Publish to PyPI
119+
uses: pypa/gh-action-pypi-publish@release/v1
120+
with:
121+
attestations: true
122+
123+
release:
124+
needs: [resolve-package, publish]
125+
runs-on: ubuntu-latest
126+
permissions:
127+
contents: write
128+
steps:
129+
- uses: actions/checkout@v6
130+
with:
131+
fetch-depth: 0
132+
133+
- name: Find previous tag for this package
134+
id: prev-tag
135+
run: |
136+
TAG="${GITHUB_REF#refs/tags/}"
137+
PREFIX="${TAG%%-v*}"
138+
PREV_TAG=$(git tag --list "${PREFIX}-v*" --sort=-v:refname | grep -v "^${TAG}$" | head -1)
139+
echo "prev-tag=${PREV_TAG}" >> "$GITHUB_OUTPUT"
140+
141+
- name: Create GitHub Release
142+
env:
143+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
144+
run: |
145+
ARGS=(
146+
"${{ github.ref_name }}"
147+
--title "${{ needs.resolve-package.outputs.package-name }} ${{ needs.resolve-package.outputs.version }}"
148+
--generate-notes
149+
)
150+
if [[ -n "${{ steps.prev-tag.outputs.prev-tag }}" ]]; then
151+
ARGS+=(--notes-start-tag "${{ steps.prev-tag.outputs.prev-tag }}")
152+
fi
153+
gh release create "${ARGS[@]}"

0 commit comments

Comments
 (0)