Skip to content

Commit 504066f

Browse files
authored
Merge pull request #138 from comet-ml/liya/OPIK-6667-add-ci-and-helm
[OPIK-6667] CI/release pipeline + Helm chart for hosted opik-mcp
2 parents ab7ac6f + 7b9594b commit 504066f

24 files changed

Lines changed: 605 additions & 100 deletions

.github/release-drafter.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
template: |
2+
## What's Changed
3+
$CHANGES

.github/workflows/ci.yaml

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
name: CI
2+
run-name: "CI ${{ github.ref_name }} by @${{ github.actor }}"
3+
4+
# CI on GitHub-hosted runners: validate, build the multi-arch image, tag releases.
5+
#
6+
# Version = <version.txt MAJOR.MINOR>.<patch>, patch = (max existing x.y tag) + 1,
7+
# so it starts at 0 and resets per minor:
8+
# push to main -> ghcr.io/comet-ml/opik-mcp:0.2.0 (+ :main, + git tag 0.2.0)
9+
# PR -> build only (no push, no secrets — fork-safe); version
10+
# carries a -<branch> suffix for the image tag if built
11+
#
12+
# Bump version.txt (e.g. 0.2 -> 0.3) to start a new minor line; patch resets to 0.
13+
# Release is manual (release.yaml): pick a git tag, promote its image, publish.
14+
15+
on:
16+
workflow_dispatch:
17+
pull_request:
18+
branches:
19+
- main
20+
push:
21+
branches:
22+
- main
23+
24+
permissions:
25+
contents: read
26+
27+
env:
28+
IMAGE: ghcr.io/comet-ml/opik-mcp
29+
30+
jobs:
31+
32+
version:
33+
runs-on: ubuntu-latest
34+
permissions:
35+
contents: write # push the git tag on main builds
36+
outputs:
37+
version: ${{ steps.v.outputs.version }} # image tag (may carry -branch)
38+
pyver: ${{ steps.v.outputs.pyver }} # PEP 440 form for the wheel
39+
steps:
40+
- uses: actions/checkout@v6
41+
with:
42+
fetch-depth: 0
43+
fetch-tags: true
44+
- name: Compute version (patch = max x.y tag + 1; tag on main)
45+
id: v
46+
env:
47+
REF_NAME: ${{ github.head_ref || github.ref_name }}
48+
EVENT: ${{ github.event_name }}
49+
run: |
50+
set -euo pipefail
51+
BASE=$(tr -d ' \t\r\n' < version.txt)
52+
if ! echo "$BASE" | grep -qE '^[0-9]+\.[0-9]+$'; then
53+
echo "::error::version.txt must be MAJOR.MINOR (x.y), got '$BASE'"; exit 1
54+
fi
55+
56+
# Highest existing patch among tags exactly "BASE.<digits>" (-1 if none → next is 0).
57+
find_max_patch() {
58+
local max=-1 rem
59+
while IFS= read -r t; do
60+
[ -z "$t" ] && continue
61+
rem="${t#"$BASE."}"
62+
if [[ "$rem" =~ ^[0-9]+$ ]] && (( rem > max )); then max=$rem; fi
63+
done < <(git tag --list "$BASE.*")
64+
echo "$max"
65+
}
66+
67+
if [ "$REF_NAME" = "main" ] && [ "$EVENT" = "push" ]; then
68+
git config user.name "github-actions"
69+
git config user.email "github-actions@comet.com"
70+
# Retry to stay race-safe if two main builds tag at once.
71+
for attempt in 1 2 3 4 5; do
72+
if [ "$attempt" -gt 1 ]; then
73+
git fetch --tags --force >/dev/null 2>&1 || true
74+
sleep $(( RANDOM % 3 + 1 ))
75+
fi
76+
PATCH=$(( $(find_max_patch) + 1 ))
77+
VERSION="$BASE.$PATCH"
78+
if git tag "$VERSION" 2>/dev/null && git push origin "refs/tags/$VERSION" 2>/dev/null; then
79+
echo "Tagged $VERSION"
80+
break
81+
fi
82+
git tag -d "$VERSION" 2>/dev/null || true
83+
if [ "$attempt" -eq 5 ]; then
84+
echo "::error::failed to create tag after 5 attempts"; exit 1
85+
fi
86+
done
87+
else
88+
PATCH=$(( $(find_max_patch) + 1 ))
89+
# Normalize: lowercase, non-alnum -> '-', cap at 20 chars,
90+
# strip trailing dashes.
91+
SLUG=$(echo "$REF_NAME" | tr '[:upper:]' '[:lower:]' | sed -E 's#[^a-z0-9]+#-#g; s#^-+##; s#-+$##')
92+
SLUG=${SLUG:0:20}; SLUG=${SLUG%-}
93+
VERSION="$BASE.$PATCH-$SLUG"
94+
fi
95+
# The image tag may carry a -branch suffix (fine for Docker tags), but
96+
# the wheel/_version.py must be PEP 440 — so branch builds use .devN.
97+
if [ "$REF_NAME" = "main" ] && [ "$EVENT" = "push" ]; then
98+
PYVER="$BASE.$PATCH"
99+
else
100+
PYVER="$BASE.$PATCH.dev0"
101+
fi
102+
echo "version=$VERSION" | tee -a "$GITHUB_OUTPUT"
103+
echo "pyver=$PYVER" | tee -a "$GITHUB_OUTPUT"
104+
echo "### Version: $VERSION" >> "$GITHUB_STEP_SUMMARY"
105+
106+
python-checks:
107+
runs-on: ubuntu-latest
108+
steps:
109+
- uses: actions/checkout@v6
110+
- name: Generate _version.py (required before any uv build)
111+
run: make version
112+
- uses: astral-sh/setup-uv@v6
113+
with:
114+
version: 'latest'
115+
- name: Install Python
116+
run: uv python install 3.13
117+
- name: Install dependencies
118+
run: uv sync --extra dev
119+
- name: Run lint + typecheck + tests
120+
run: make check
121+
122+
helm-lint:
123+
runs-on: ubuntu-latest
124+
steps:
125+
- uses: actions/checkout@v6
126+
- uses: azure/setup-helm@v4
127+
with:
128+
version: v3.16.2
129+
- name: Helm lint
130+
run: helm lint helm/opik-mcp -f helm/opik-mcp/values.yaml
131+
- name: Helm template
132+
run: helm template opik-mcp helm/opik-mcp -f helm/opik-mcp/values.yaml > /dev/null
133+
134+
build-image:
135+
needs: version
136+
runs-on: ubuntu-latest
137+
permissions:
138+
contents: read
139+
packages: write
140+
steps:
141+
- uses: actions/checkout@v6
142+
- name: Generate _version.py (baked into the image via COPY src)
143+
run: VERSION="${{ needs.version.outputs.pyver }}" make version
144+
- uses: docker/setup-qemu-action@v3
145+
- uses: docker/setup-buildx-action@v3
146+
- name: Login to GHCR
147+
if: github.event_name != 'pull_request'
148+
uses: docker/login-action@v3
149+
with:
150+
registry: ghcr.io
151+
username: ${{ github.actor }}
152+
password: ${{ secrets.GITHUB_TOKEN }}
153+
- name: Build and push (push only off PRs)
154+
uses: docker/build-push-action@v6
155+
with:
156+
context: .
157+
file: Dockerfile
158+
platforms: linux/amd64,linux/arm64
159+
push: ${{ github.event_name != 'pull_request' }}
160+
tags: |
161+
${{ env.IMAGE }}:${{ needs.version.outputs.version }}
162+
${{ github.ref_name == 'main' && format('{0}:main', env.IMAGE) || '' }}
163+
cache-from: type=gha
164+
cache-to: type=gha,mode=max

.github/workflows/legacy-ts-ci.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
name: Legacy TS CI
22

33
on:
4-
pull_request:
5-
branches: [ main ]
6-
paths:
7-
- 'legacy/typescript/**'
8-
- '.github/workflows/legacy-ts-ci.yml'
4+
# Auto-trigger (pull_request) disabled — manual-only.
5+
# Legacy TypeScript package is deprecated; run from the Actions tab if needed.
6+
workflow_dispatch:
97

108
jobs:
119
ci:
@@ -16,7 +14,7 @@ jobs:
1614

1715
steps:
1816
- name: Checkout code
19-
uses: actions/checkout@v4
17+
uses: actions/checkout@v6
2018

2119
- name: Setup Node.js
2220
uses: actions/setup-node@v4

.github/workflows/legacy-ts-deploy.yml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
name: Publish Release (Legacy TS)
22

33
on:
4-
push:
5-
tags:
6-
- "npm-v*"
4+
# Tag auto-trigger (npm-v*) disabled — manual-only.
5+
# Deprecated TS package; dispatch from an npm-v* tag ref to publish.
76
workflow_dispatch:
87

98
jobs:
@@ -19,7 +18,7 @@ jobs:
1918

2019
steps:
2120
- name: Checkout code
22-
uses: actions/checkout@v4
21+
uses: actions/checkout@v6
2322

2423
- name: Setup Node.js
2524
uses: actions/setup-node@v4

.github/workflows/python-ci.yml

Lines changed: 0 additions & 30 deletions
This file was deleted.

.github/workflows/python-release.yml

Lines changed: 0 additions & 53 deletions
This file was deleted.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Release Drafter
2+
3+
# Keeps a draft GitHub release continuously updated with the changes merged to
4+
# main (one entry per merged PR). The draft is published/cleaned up by the
5+
# Release workflow's delete-draft step when an actual release is cut.
6+
7+
on:
8+
push:
9+
branches:
10+
- main
11+
12+
permissions:
13+
contents: write # create/update the draft release
14+
pull-requests: read # read merged PRs for the changelog
15+
16+
jobs:
17+
update_release_draft:
18+
runs-on: ubuntu-latest
19+
timeout-minutes: 5
20+
steps:
21+
- uses: release-drafter/release-drafter@v7
22+
env:
23+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

0 commit comments

Comments
 (0)