Skip to content

Commit 77b5636

Browse files
committed
add release pipeline for mlflow
1 parent 8b3d469 commit 77b5636

File tree

4 files changed

+230
-29
lines changed

4 files changed

+230
-29
lines changed

.github/workflows/mlflow-ci.yml

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
name: MLflow CI
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- 'applications/mlflow/charts/**'
7+
- 'applications/mlflow/kots/**'
8+
- '.github/workflows/mlflow-ci.yml'
9+
push:
10+
branches:
11+
- main
12+
paths:
13+
- 'applications/mlflow/charts/**'
14+
- 'applications/mlflow/kots/**'
15+
- '.github/workflows/mlflow-ci.yml'
16+
17+
env:
18+
APP_SLUG: mlflow
19+
20+
jobs:
21+
lint:
22+
runs-on: ubuntu-22.04
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
with:
27+
fetch-depth: 0
28+
29+
- name: Set up Helm
30+
uses: azure/setup-helm@v3
31+
with:
32+
version: v4.3.0
33+
34+
- name: Set up Python
35+
uses: actions/setup-python@v3
36+
with:
37+
python-version: 3.12
38+
39+
- name: Set up chart-testing
40+
uses: helm/[email protected]
41+
with:
42+
version: v3.8.0
43+
44+
- name: Run chart-testing (lint)
45+
run: ct lint --config applications/mlflow/ct.yaml --chart-dirs applications/mlflow/charts --charts applications/mlflow/charts/mlflow applications/mlflow/charts/infra
46+
47+
test:
48+
runs-on: ubuntu-22.04
49+
needs: [lint]
50+
strategy:
51+
fail-fast: false
52+
matrix:
53+
cluster:
54+
- distribution: kind
55+
version: 1.32.3
56+
- distribution: k3s
57+
version: 1.32.3
58+
- distribution: aks
59+
version: 1.31
60+
- distribution: gke
61+
version: 1.32
62+
steps:
63+
- name: Checkout
64+
uses: actions/checkout@v4
65+
with:
66+
fetch-depth: 0
67+
68+
- name: Set up Helm
69+
uses: azure/setup-helm@v3
70+
with:
71+
version: v4.3.0
72+
73+
- name: Create Cluster
74+
id: create-cluster
75+
uses: replicatedhq/replicated-actions/[email protected]
76+
with:
77+
api-token: ${{ secrets.REPLICATED_PLATFORM_EXAMPLES_TOKEN }}
78+
kubernetes-distribution: ${{ matrix.cluster.distribution }}
79+
kubernetes-version: ${{ matrix.cluster.version }}
80+
cluster-name: mlflow-e2e-${{ github.run_id }}-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}
81+
ttl: 1h
82+
83+
- name: Install Infra Chart
84+
run: ct install --config applications/mlflow/ct.yaml --chart-dirs applications/mlflow/charts --charts applications/mlflow/charts/mlflow --skip-clean-up --namespace default
85+
env:
86+
KUBECONFIG: ${{ steps.create-cluster.outputs.cluster-kubeconfig }}
87+
88+
- name: Install Mlflow Chart
89+
run: ct install --config applications/mlflow/ct.yaml --chart-dirs applications/mlflow/charts --charts applications/mlflow/charts/mlflow --skip-clean-up --namespace default
90+
env:
91+
KUBECONFIG: ${{ steps.create-cluster.outputs.cluster-kubeconfig }}
92+
93+
- name: Install troubleshoot
94+
run: curl -L https://github.com/replicatedhq/troubleshoot/releases/latest/download/support-bundle_linux_amd64.tar.gz | tar xzvf -
95+
if: failure()
96+
97+
- name: Collect bundle
98+
run: ./support-bundle --kubeconfig=${{ steps.create-cluster.outputs.cluster-kubeconfig }} --interactive=false -o ci-bundle-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }} https://raw.githubusercontent.com/replicatedhq/troubleshoot-specs/main/in-cluster/default.yaml
99+
env:
100+
KUBECONFIG: ${{ steps.create-cluster.outputs.cluster-kubeconfig }}
101+
if: failure()
102+
103+
- name: Upload support bundle artifact
104+
uses: actions/upload-artifact@v3
105+
if: failure()
106+
with:
107+
name: mlflow-bundle-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}
108+
path: 'ci-bundle-${{ matrix.cluster.distribution }}-${{ matrix.cluster.version }}.tar.gz'
109+
110+
- name: Remove Cluster
111+
uses: replicatedhq/replicated-actions/[email protected]
112+
if: ${{ always() && steps.create-cluster.outputs.cluster-id != '' }}
113+
with:
114+
api-token: ${{ secrets.REPLICATED_PLATFORM_EXAMPLES_TOKEN }}
115+
cluster-id: ${{ steps.create-cluster.outputs.cluster-id }}
116+
117+
create-release:
118+
runs-on: ubuntu-22.04
119+
needs: [test]
120+
if: github.event_name == 'push' || github.event_name == 'release'
121+
steps:
122+
- name: Checkout
123+
uses: actions/checkout@v4
124+
with:
125+
fetch-depth: 0
126+
127+
- name: Set up Helm
128+
uses: azure/setup-helm@v3
129+
with:
130+
version: v4.3.0
131+
132+
- name: Package infra chart
133+
run: |
134+
helm package applications/mlflow/charts/infra -d applications/mlflow/kots/ -u
135+
if [ ! -f applications/mlflow/kots/infra-*.tgz ]; then
136+
echo "Error: Infra chart packaging failed"
137+
exit 1
138+
fi
139+
140+
- name: Package mlflow chart
141+
run: |
142+
helm package applications/mlflow/charts/mlflow -d applications/mlflow/kots/ -u
143+
if [ ! -f applications/mlflow/kots/mlflow-*.tgz ]; then
144+
echo "Error: MLflow chart packaging failed"
145+
exit 1
146+
fi
147+
148+
# The following steps implement our versioning strategy:
149+
# 1. We extract the chart version from mlflow-chart.yaml
150+
# 2. We use this version for the Replicated release
151+
# This ensures that the Replicated release version always matches the MLflow chart version
152+
- name: Extract MLflow chart version
153+
id: chart-version
154+
run: |
155+
CHART_VERSION=$(grep 'chartVersion:' applications/mlflow/kots/mlflow-chart.yaml | awk '{print $2}')
156+
echo "CHART_VERSION=$CHART_VERSION" >> $GITHUB_ENV
157+
echo "Using MLflow chart version: $CHART_VERSION"
158+
159+
- name: Create release
160+
id: create-release
161+
uses: replicatedhq/replicated-actions/[email protected]
162+
with:
163+
app-slug: ${{ env.APP_SLUG }}
164+
api-token: ${{ secrets.REPLICATED_PLATFORM_EXAMPLES_TOKEN }}
165+
yaml-dir: applications/mlflow/kots/
166+
promote-channel: ci-automation-${{ github.run_id }}
167+
version: ${{ env.CHART_VERSION }}
168+
169+
cleanup-test-release:
170+
runs-on: ubuntu-22.04
171+
needs: [test, create-release]
172+
steps:
173+
- name: Archive Customer
174+
if: ${{ needs.create-release.outputs.customer-id != '' }}
175+
uses: replicatedhq/replicated-actions/[email protected]
176+
with:
177+
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }}
178+
customer-id: ${{ needs.create-release.outputs.customer-id }}
179+
180+
- name: Archive Channel
181+
if: ${{ needs.create-release.outputs.channel-slug != '' }}
182+
uses: replicatedhq/replicated-actions/[email protected]
183+
with:
184+
app-slug: ${{ env.APP_SLUG }}
185+
api-token: ${{ secrets.C11Y_MATRIX_TOKEN }}
186+
channel-slug: ${{ needs.create-release.outputs.channel-slug }}

applications/mlflow/README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Mlflow
1+
# MLflow
22

33
## Get Started
44

@@ -8,4 +8,19 @@
88

99
## Embedded Cluster
1010

11-
## Running the Mlflow Quickstart Example
11+
## Running the MLflow Quickstart Example
12+
13+
## CI/CD Pipeline
14+
15+
This application includes a CI/CD pipeline implemented with GitHub Actions. The pipeline handles:
16+
17+
- Linting and testing the Helm chart
18+
- Installing the chart in a test cluster
19+
- Creating releases in Replicated channels
20+
- Generating Kubernetes installers
21+
22+
The pipeline is triggered on:
23+
- Pull requests affecting the MLflow application
24+
- Pushes to the main branch
25+
26+
For more details, see [planning.md](./planning.md) and the workflow definition in [.github/workflows/mlflow-ci.yml](../../.github/workflows/mlflow-ci.yml).
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
dependencies:
22
- name: replicated
33
repository: oci://registry.replicated.com/library
4-
version: 1.1.0
5-
digest: sha256:9debf14266b4425bcc68a80da11527f8d0c5e68f678cae676179557bab423ae6
6-
generated: "2025-02-09T00:40:36.875661-05:00"
4+
version: 1.5.0
5+
digest: sha256:47a29e041d280e6e5db79c0dcf469b5c43cef2d780169fa7cd40e9b02e9b1fd5
6+
generated: "2025-04-07T10:50:18.860452-04:00"

applications/mlflow/charts/mlflow/values.yaml

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -87,20 +87,20 @@ mlflow:
8787
# secretKeyRef:
8888
# name: extra-env-secret
8989
# key: extra-env-key-3
90-
90+
9191
# -- Extra initialization containers belonging to the mlflow pod.
9292
extraInitContainers: []
93-
93+
9494
# -- Extra containers belonging to the mlflow pod.
9595
extraContainers: []
96-
96+
9797
# -- Extra environment variable sources in mlflow container
9898
extraEnvFrom: []
9999
# - configMapRef:
100100
# name: extra-env-configmap
101101
# - secretRef:
102102
# name: extra-env-secret
103-
103+
104104
# -- Extra volumes that can be mounted by containers belonging to the mlflow pod
105105
extraVolumes: []
106106
# - name: mlflow-volume
@@ -109,7 +109,7 @@ mlflow:
109109
# - name: mlflow-configmap-volume
110110
# configMap:
111111
# name: mlflow-configmap
112-
112+
113113
# -- Extra volume mounts to mount into the mlflow container's file system
114114
extraVolumeMounts: []
115115
# - name: mlflow-volume
@@ -172,7 +172,7 @@ mlflow:
172172
# -- Enable/disable the generation of environment variables for services.
173173
# [[ref]](https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#accessing-the-service)
174174
enableServiceLinks: true
175-
175+
176176
# -- Configure the lifecycle for the container
177177
lifecycle: {}
178178
termination:
@@ -200,7 +200,7 @@ mlflow:
200200
name: http
201201
# -- Annotations to add to the service
202202
annotations: {}
203-
203+
204204
# -- Mlflow Ingress configuration
205205
# [[ref]](https://kubernetes.io/docs/concepts/services-networking/ingress/)
206206
ingress:
@@ -262,7 +262,7 @@ mlflow:
262262
# - --expose-prometheus /metrics
263263
# If enabled, run the server with debug logging and auto-reload
264264
- --dev
265-
265+
266266
# Basic authentication configuration,
267267
# for more information, please visit https://mlflow.org/docs/latest/auth/index.html#configuration
268268
basicAuth:
@@ -349,7 +349,7 @@ minio:
349349
pullPolicy: IfNotPresent
350350
# -- Image pull secrets
351351
imagePullSecret: {}
352-
# --
352+
# --
353353
scheduler: {}
354354
# -- The Kubernetes secret name that contains MinIO environment variable configurations.
355355
# The secret is expected to have a key named config.env containing environment variables exports.
@@ -389,7 +389,7 @@ minio:
389389
# [[ref]](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity)
390390
podAntiAffinityMode: "soft"
391391
# -- The `Requests or Limits <https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/>`__ for resources to associate to Tenant pods.
392-
resources: { }
392+
resources: {}
393393
# -- The Kubernetes `SecurityContext <https://kubernetes.io/docs/tasks/configure-pod-container/security-context/>`__ to use for deploying Tenant resources.
394394
securityContext:
395395
runAsUser: 1000
@@ -409,7 +409,7 @@ minio:
409409
seccompProfile:
410410
type: RuntimeDefault
411411
# -- An array of `Topology Spread Constraints <https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/>`__ to associate to Operator Console pods.
412-
topologySpreadConstraints: [ ]
412+
topologySpreadConstraints: []
413413
# -- The name of a custom `Container Runtime <https://kubernetes.io/docs/concepts/containers/runtime-class/>`__ to use for the Operator Console pods.
414414
runtimeClassName: ""
415415
# -- The mount path where Persistent Volumes are mounted inside Tenant container(s).
@@ -428,7 +428,7 @@ minio:
428428
externalCaCertSecret: []
429429
# -- Specify an array of Kubernetes secrets, where each entry corresponds to a secret contains the TLS private key and public certificate pair.
430430
# See `Operator CRD: TenantSpec <https://min.io/docs/minio/kubernetes/upstream/reference/operator-crd.html#tenantspec>`__.
431-
externalCertSecret: [ ]
431+
externalCertSecret: []
432432
# Enable automatic Kubernetes based `certificate generation and signing <https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster>`__
433433
requestAutoCert: true
434434
# -- See `Operator CRD: CertificateConfig <https://min.io/docs/minio/kubernetes/upstream/reference/operator-crd.html#certificateconfig>`__
@@ -445,25 +445,25 @@ minio:
445445
# -- Array of Kubernetes secrets from which the Operator generates MinIO users during tenant provisioning.
446446
# Each secret should specify the ``CONSOLE_ACCESS_KEY`` and ``CONSOLE_SECRET_KEY`` as the access key and secret key for that user.
447447
users: []
448-
# -- The `PodManagement <https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#pod-management-policy>`__ policy for MinIO Tenant Pods.
448+
# -- The `PodManagement <https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/#pod-management-policy>`__ policy for MinIO Tenant Pods.
449449
# Can be "OrderedReady" or "Parallel"
450450
podManagementPolicy: Parallel
451-
# -- The `Liveness Probe <https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes>`__ for monitoring Tenant pod liveness.
451+
# -- The `Liveness Probe <https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes>`__ for monitoring Tenant pod liveness.
452452
# Tenant pods will be restarted if the probe fails.
453453
liveness: {}
454454
# -- `Readiness Probe <https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/>`__ for monitoring Tenant container readiness.
455455
# Tenant pods will be removed from service endpoints if the probe fails.
456-
# -- `Startup Probe <https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/>`__ for monitoring container startup.
456+
# -- `Startup Probe <https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/>`__ for monitoring container startup.
457457
# Tenant pods will be restarted if the probe fails.
458458
startup: {}
459459
# -- The `Lifecycle hooks <https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/>`__ for container.
460-
lifecycle: { }
460+
lifecycle: {}
461461
# -- Directs the Operator to deploy the MinIO S3 API and Console services as LoadBalancer objects.
462462
# If the Kubernetes cluster has a configured LoadBalancer, it can attempt to route traffic to those services automatically.
463463
# Specify ``minio: true`` to expose the MinIO S3 API.
464464
# Specify ``console: true`` to expose the Console.
465465
# Both fields default to ``false``.
466-
exposeServices: { }
466+
exposeServices: {}
467467
# -- The `Kubernetes Service Account <https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/>`__ associated with the Tenant.
468468
serviceAccountName: ""
469469
# -- Directs the Operator to add the Tenant's metric scrape configuration to an existing Kubernetes Prometheus deployment managed by the Prometheus Operator.
@@ -472,24 +472,24 @@ minio:
472472
# Specify ``json`` for JSON-formatted logs.
473473
# Specify ``anonymous`` for anonymized logs.
474474
# Specify ``quiet`` to supress logging.
475-
logging: { }
475+
logging: {}
476476
# -- serviceMetadata allows passing additional labels and annotations to MinIO and Console specific
477477
# services created by the operator.
478-
serviceMetadata: { }
478+
serviceMetadata: {}
479479
# -- Add environment variables to be set in MinIO container (https://github.com/minio/minio/tree/master/docs/config)
480-
env: [ ]
480+
env: []
481481
# -- PriorityClassName indicates the Pod priority and hence importance of a Pod relative to other Pods.
482482
# This is applied to MinIO pods only.
483483
# Refer Kubernetes documentation for details https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass/
484484
priorityClassName: ""
485485
# -- An array of `Volumes <https://kubernetes.io/docs/concepts/storage/volumes/>`__ which the Operator can mount to Tenant pods.
486486
# The volumes must exist *and* be accessible to the Tenant pods.
487-
additionalVolumes: [ ]
487+
additionalVolumes: []
488488
# -- An array of volume mount points associated to each Tenant container.
489-
additionalVolumeMounts: [ ]
489+
additionalVolumeMounts: []
490490
# Define configuration for KES (stateless and distributed key-management system)
491491
# Refer https://github.com/minio/kes
492-
#kes:
492+
# kes:
493493
# ## Image field:
494494
# # Image from tag (original behavior), for example:
495495
# # image:
@@ -660,7 +660,7 @@ postgres:
660660
# and then blank the password of the postgres user by setting it to NULL.
661661
enableSuperuserAccess: true
662662
superuserSecret: ""
663-
663+
664664
# -- This feature enables declarative management of existing roles, as well as the creation of new roles if they are not
665665
# already present in the database.
666666
# See: https://cloudnative-pg.io/documentation/current/declarative_role_management/

0 commit comments

Comments
 (0)