@@ -11,114 +11,145 @@ env:
1111 IMAGE_NAME : ${{ github.repository }}
1212
1313jobs :
14- release :
15- name : Create Release
14+ build_dist :
15+ name : Build sdist/wheel and verify version
1616 runs-on : ubuntu-latest
1717 permissions :
18- contents : write
19- packages : write
18+ contents : read
2019 id-token : write
21-
2220 steps :
23- - name : Checkout code
24- uses : actions/checkout@v5
25- with :
26- fetch-depth : 0
27-
28- - name : Install uv
29- uses : astral-sh/setup-uv@v6
30- with :
31- version : " latest"
32-
33- - name : Set up Python
34- run : uv python install ${{ env.PYTHON_VERSION }}
35-
36- - name : Install dependencies
37- run : uv sync --all-extras --dev
38-
39- - name : Extract version from tag
40- id : version
41- run : |
42- VERSION=${GITHUB_REF#refs/tags/v}
43- echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
44- echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
45-
46- - name : Verify version matches pyproject.toml
47- run : |
48- PROJECT_VERSION=$(uv run python -c "import tomllib; print(tomllib.load(open('pyproject.toml', 'rb'))['project']['version'])")
49- if [ "$PROJECT_VERSION" != "${{ steps.version.outputs.VERSION }}" ]; then
50- echo "Version mismatch: tag=${{ steps.version.outputs.VERSION }}, pyproject.toml=$PROJECT_VERSION"
51- exit 1
52- fi
53-
54- - name : Generate changelog
55- id : changelog
56- run : |
57- # Simple changelog generation - you can enhance this
58- echo "CHANGELOG<<EOF" >> $GITHUB_OUTPUT
59- echo "## Changes in ${{ steps.version.outputs.TAG }}" >> $GITHUB_OUTPUT
60- git log --pretty=format:"- %s" $(git describe --tags --abbrev=0 HEAD^)..HEAD >> $GITHUB_OUTPUT || echo "- Initial release" >> $GITHUB_OUTPUT
61- echo "" >> $GITHUB_OUTPUT
62- echo "EOF" >> $GITHUB_OUTPUT
63-
64- - name : Clean dist directory
65- run : |
66- rm -rf dist/
67-
68- - name : Build package
69- run : |
70- uv build --no-sources
71-
72- - name : Publish to PyPI
73- uses : pypa/gh-action-pypi-publish@release/v1
74- with :
75- password : ${{ secrets.PYPI_API_TOKEN }}
76-
77- - name : Log in to Container Registry
78- uses : docker/login-action@v3
79- with :
80- registry : ${{ env.REGISTRY }}
81- username : ${{ github.actor }}
82- password : ${{ secrets.GITHUB_TOKEN }}
83-
84- - name : Extract metadata for Docker
85- id : meta
86- uses : docker/metadata-action@v5
87- with :
88- images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
89- tags : |
90- type=ref,event=tag
91- type=semver,pattern={{version}}
92- type=semver,pattern={{major}}.{{minor}}
93- type=semver,pattern={{major}}
94- type=raw,value=latest,enable={{is_default_branch}}
95-
96- - name : Set up Docker Buildx
97- uses : docker/setup-buildx-action@v3
98-
99- - name : Build and push Docker image
100- uses : docker/build-push-action@v6
101- with :
102- context : .
103- platforms : linux/amd64,linux/arm64
104- push : true
105- tags : ${{ steps.meta.outputs.tags }}
106- labels : ${{ steps.meta.outputs.labels }}
107- build-args : |
108- VERSION=${{ steps.version.outputs.VERSION }}
109- cache-from : type=gha
110- cache-to : type=gha,mode=max
111-
112- - name : Create GitHub Release
113- uses : softprops/action-gh-release@v2
114- with :
115- tag_name : ${{ steps.version.outputs.TAG }}
116- name : Release ${{ steps.version.outputs.TAG }}
117- body : ${{ steps.changelog.outputs.CHANGELOG }}
118- draft : false
119- prerelease : false
120- files : |
121- dist/*
122- generate_release_notes : true
123- env :
124- GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
21+ - uses : actions/checkout@v5
22+ with :
23+ fetch-depth : 0
24+ - uses : astral-sh/setup-uv@v6
25+ with :
26+ version : latest
27+ - name : Set up Python
28+ run : uv python install ${{ env.PYTHON_VERSION }}
29+ - name : Extract version from tag
30+ id : ver
31+ run : |
32+ VERSION=${GITHUB_REF#refs/tags/v}
33+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
34+ echo "TAG=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
35+ - name : Verify version matches pyproject.toml
36+ run : |
37+ PROJECT_VERSION=$(uv run python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
38+ test "$PROJECT_VERSION" = "${{ steps.ver.outputs.VERSION }}"
39+ - name : Clean dist directory
40+ run : rm -rf dist/
41+ - name : Build package
42+ run : uv build --no-sources
43+ - name : Upload dist artifacts
44+ uses : actions/upload-artifact@v4
45+ with :
46+ name : dist
47+ path : dist/*
48+
49+ publish_pypi :
50+ name : Publish to PyPI
51+ needs : build_dist
52+ runs-on : ubuntu-latest
53+ permissions :
54+ contents : read
55+ id-token : write
56+ steps :
57+ - uses : actions/download-artifact@v4
58+ with :
59+ name : dist
60+ path : dist
61+ - name : Publish to PyPI
62+ uses : pypa/gh-action-pypi-publish@release/v1
63+ with :
64+ password : ${{ secrets.PYPI_API_TOKEN }}
65+
66+ docker_build_push :
67+ name : Build & push multi-arch image
68+ runs-on : ubuntu-latest
69+ permissions :
70+ contents : read
71+ packages : write
72+ steps :
73+ - uses : actions/checkout@v5
74+ - name : Extract version from tag
75+ id : ver
76+ run : |
77+ VERSION=${GITHUB_REF#refs/tags/v}
78+ echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
79+ - uses : docker/login-action@v3
80+ with :
81+ registry : ${{ env.REGISTRY }}
82+ username : ${{ github.actor }}
83+ password : ${{ secrets.GITHUB_TOKEN }}
84+ - id : meta
85+ uses : docker/metadata-action@v5
86+ with :
87+ images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
88+ tags : |
89+ type=ref,event=tag
90+ type=semver,pattern={{version}}
91+ type=semver,pattern={{major}}.{{minor}}
92+ type=semver,pattern={{major}}
93+ type=raw,value=latest,enable={{is_default_branch}}
94+ - uses : docker/setup-buildx-action@v3
95+ - uses : docker/build-push-action@v6
96+ with :
97+ context : .
98+ platforms : linux/amd64,linux/arm64
99+ push : true
100+ tags : ${{ steps.meta.outputs.tags }}
101+ labels : ${{ steps.meta.outputs.labels }}
102+ build-args : |
103+ VERSION=${{ steps.ver.outputs.VERSION }}
104+ cache-from : type=gha
105+ cache-to : type=gha,mode=max
106+
107+ create_release :
108+ name : Create GitHub Release with artifacts
109+ needs : build_dist
110+ runs-on : ubuntu-latest
111+ permissions :
112+ contents : write
113+ steps :
114+ - uses : actions/checkout@v5
115+ with :
116+ fetch-depth : 0
117+ - name : Generate changelog
118+ id : changelog
119+ run : |
120+ echo "CHANGELOG<<EOF" >> $GITHUB_OUTPUT
121+ echo "## Changes in ${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
122+ git log --pretty=format:"- %s" $(git describe --tags --abbrev=0 HEAD^)..HEAD >> $GITHUB_OUTPUT || echo "- Initial release" >> $GITHUB_OUTPUT
123+ echo "" >> $GITHUB_OUTPUT
124+ echo "EOF" >> $GITHUB_OUTPUT
125+ - uses : actions/download-artifact@v4
126+ with :
127+ name : dist
128+ path : dist
129+ - uses : softprops/action-gh-release@v2
130+ with :
131+ tag_name : ${GITHUB_REF#refs/tags/}
132+ name : Release ${GITHUB_REF#refs/tags/}
133+ body : ${{ steps.changelog.outputs.CHANGELOG }}
134+ draft : false
135+ prerelease : false
136+ files : |
137+ dist/*
138+ generate_release_notes : true
139+
140+ publish_mcp_registry :
141+ name : Publish to MCP Registry (preview)
142+ runs-on : macos-latest
143+ permissions :
144+ contents : read
145+ continue-on-error : true
146+ steps :
147+ - uses : actions/checkout@v5
148+ - name : Install MCP Publisher CLI
149+ run : brew install mcp-publisher
150+ - name : Initialize server metadata (idempotent)
151+ run : mcp-publisher init || true
152+ - name : Publish to MCP Registry
153+ env :
154+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
155+ run : mcp-publisher publish
0 commit comments