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