Skip to content

Commit af2baa8

Browse files
committed
Use setuptools-scm for git-tag-driven versioning, fix CI/Release workflows
- pyproject.toml: replace static version with dynamic setuptools-scm - Dockerfile: accept VERSION build arg via SETUPTOOLS_SCM_PRETEND_VERSION - .dockerignore: exclude .git and dev artifacts from Docker context - ci.yml: only push :main tag (not :latest) - release.yml: derive version from git tags, no commits to main, pass VERSION build arg, upgrade gh-release action to v2
1 parent 9b54cd6 commit af2baa8

5 files changed

Lines changed: 54 additions & 33 deletions

File tree

.dockerignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.git
2+
.github
3+
.venv
4+
__pycache__
5+
*.pyc
6+
.pytest_cache
7+
junit/
8+
coverage.xml
9+
.env

.github/workflows/ci.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,7 @@ jobs:
8181
push: true
8282
platforms: linux/amd64,linux/arm64
8383
file: ./Dockerfile
84-
tags: |
85-
${{ env.IMAGE_NAME }}:main
86-
${{ env.IMAGE_NAME }}:latest
84+
tags: ${{ env.IMAGE_NAME }}:main
8785
labels: |
8886
io.modelcontextprotocol.server.name=io.github.CodeAlive-AI/codealive-mcp
8987
cache-from: type=gha

.github/workflows/release.yml

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ on:
44
workflow_dispatch:
55
inputs:
66
version:
7-
description: 'Exact version (e.g. 0.6.0). Takes precedence over bump_type.'
7+
description: 'Exact version (e.g. 0.6.0). Leave empty to auto-calculate from bump_type.'
88
required: false
99
type: string
1010
bump_type:
11-
description: 'Version bump type (used if version is empty)'
11+
description: 'Version bump type (used when version is empty)'
1212
required: false
1313
type: choice
1414
default: patch
@@ -23,15 +23,13 @@ env:
2323

2424
permissions:
2525
id-token: write # MCP Registry OIDC authentication
26-
contents: write # Git tags, releases, push version bump
26+
contents: write # Git tags and GitHub Releases
2727
packages: write # Docker push to GHCR
2828

2929
jobs:
3030
release:
3131
name: Release
3232
runs-on: ubuntu-latest
33-
# Requires the "release" environment — configure protection rules in
34-
# Settings > Environments to restrict to admins/maintainers
3533
environment: release
3634
steps:
3735
- name: Checkout repository
@@ -58,7 +56,12 @@ jobs:
5856
- name: Calculate version
5957
id: version
6058
run: |
61-
CURRENT=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
59+
# Derive current version from the latest git tag (single source of truth)
60+
CURRENT=$(git tag --sort=-v:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -1 | sed 's/^v//')
61+
if [ -z "$CURRENT" ]; then
62+
CURRENT="0.0.0"
63+
echo "::warning::No existing version tags found, starting from 0.0.0"
64+
fi
6265
echo "current=$CURRENT" >> $GITHUB_OUTPUT
6366
6467
if [ -n "${{ inputs.version }}" ]; then
@@ -73,25 +76,32 @@ jobs:
7376
esac
7477
fi
7578
79+
# Validate version format
80+
if ! echo "$VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
81+
echo "::error::Invalid version format: $VERSION (expected X.Y.Z)"
82+
exit 1
83+
fi
84+
85+
# Check if tag already exists
7686
if git tag -l "v$VERSION" | grep -q "v$VERSION"; then
77-
echo "::error::Tag v$VERSION already exists"
87+
echo "::error::Tag v$VERSION already exists. Delete it first or choose a different version."
7888
exit 1
7989
fi
8090
8191
echo "version=$VERSION" >> $GITHUB_OUTPUT
82-
echo "### 🚀 Releasing $CURRENT → $VERSION" >> $GITHUB_STEP_SUMMARY
92+
echo "### Releasing $CURRENT → $VERSION" >> $GITHUB_STEP_SUMMARY
8393
84-
- name: Update pyproject.toml version
94+
- name: Prepare server.json for publish
8595
run: |
86-
sed -i 's/^version = ".*"/version = "${{ steps.version.outputs.version }}"/' pyproject.toml
96+
VERSION="${{ steps.version.outputs.version }}"
8797
88-
- name: Update server.json version
89-
run: |
98+
# Update server.json in working directory (not committed)
99+
# pyproject.toml uses setuptools-scm — version comes from Docker build arg
90100
python -c "
91101
import json
92102
with open('server.json', 'r') as f:
93103
data = json.load(f)
94-
version = '${{ steps.version.outputs.version }}'
104+
version = '$VERSION'
95105
data['version'] = version
96106
if 'packages' in data:
97107
for package in data['packages']:
@@ -106,6 +116,8 @@ jobs:
106116
f.write('\n')
107117
"
108118
119+
echo "Updated server.json to $VERSION (working dir only)"
120+
109121
- name: Validate server.json
110122
run: |
111123
python -c "
@@ -117,7 +129,7 @@ jobs:
117129
with open('server.json', 'r') as f:
118130
data = json.load(f)
119131
validate(instance=data, schema=schema)
120-
print('server.json validation passed')
132+
print('server.json validation passed')
121133
"
122134
123135
- name: Set up Docker Buildx
@@ -136,6 +148,7 @@ jobs:
136148
push: true
137149
platforms: linux/amd64,linux/arm64
138150
file: ./Dockerfile
151+
build-args: VERSION=${{ steps.version.outputs.version }}
139152
tags: |
140153
${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}
141154
${{ env.IMAGE_NAME }}:v${{ steps.version.outputs.version }}
@@ -145,39 +158,34 @@ jobs:
145158
cache-from: type=gha
146159
cache-to: type=gha
147160

148-
# Git operations happen AFTER Docker push — if Docker fails, repo stays clean
149-
- name: Commit version bump and create tag
161+
# Git tag created AFTER Docker push succeeds — if Docker fails, no stale tag
162+
- name: Create and push git tag
150163
run: |
151164
git config user.name "github-actions[bot]"
152165
git config user.email "github-actions[bot]@users.noreply.github.com"
153-
git add pyproject.toml server.json
154-
git commit -m "chore: release v${{ steps.version.outputs.version }} [skip ci]"
155-
git tag "v${{ steps.version.outputs.version }}"
156-
git push origin main --tags
166+
git tag -a "v${{ steps.version.outputs.version }}" -m "Release v${{ steps.version.outputs.version }}"
167+
git push origin "v${{ steps.version.outputs.version }}"
157168
158169
- name: Install MCP Publisher CLI
159170
run: |
160171
curl -L "https://github.com/modelcontextprotocol/registry/releases/download/v1.5.0/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
161172
chmod +x mcp-publisher
162-
./mcp-publisher version || true
163173
164174
- name: Login to MCP Registry (GitHub OIDC)
165-
run: |
166-
./mcp-publisher login github-oidc
175+
run: ./mcp-publisher login github-oidc
167176

168177
- name: Publish to MCP Registry
169-
run: |
170-
./mcp-publisher publish
178+
run: ./mcp-publisher publish
171179

172180
- name: Create GitHub Release
173-
uses: softprops/action-gh-release@v1
181+
uses: softprops/action-gh-release@v2
174182
with:
175183
tag_name: v${{ steps.version.outputs.version }}
176184
name: CodeAlive MCP v${{ steps.version.outputs.version }}
177185
body: |
178186
## CodeAlive MCP Server v${{ steps.version.outputs.version }}
179187
180-
### 🚀 Deployment Options
188+
### Deployment Options
181189
182190
**Docker Container (Local)**
183191
```bash

Dockerfile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ FROM python:3.11-slim AS base
55
# MCP Server validation label for Docker registry
66
LABEL io.modelcontextprotocol.server.name="io.github.CodeAlive-AI/codealive-mcp"
77

8+
# Version injected at build time for setuptools-scm
9+
ARG VERSION=0.0.0
10+
ENV SETUPTOOLS_SCM_PRETEND_VERSION=$VERSION
11+
812
# Set working directory
913
WORKDIR /app
1014

pyproject.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "codealive-mcp"
3-
version = "0.5.1"
3+
dynamic = ["version"]
44
description = "MCP server for the CodeAlive API"
55
readme = "README.md"
66
requires-python = ">=3.11"
@@ -23,9 +23,11 @@ test = [
2323
codealive-mcp = "codealive_mcp.server:main"
2424

2525
[build-system]
26-
requires = ["setuptools>=61.0"]
26+
requires = ["setuptools>=61.0", "setuptools-scm>=8"]
2727
build-backend = "setuptools.build_meta"
2828

2929
[tool.setuptools]
3030
packages = ["src"]
31-
package-dir = {"" = "."}
31+
package-dir = {"" = "."}
32+
33+
[tool.setuptools_scm]

0 commit comments

Comments
 (0)