From 261647cf3941c93ac332427e3831e0c3a676dd18 Mon Sep 17 00:00:00 2001 From: Bill Yang Date: Thu, 23 Jul 2026 12:50:07 -0700 Subject: [PATCH] ci: auto-publish model-engine helm chart to public ECR on merge Adds a main-only publish_helm_chart CircleCI job (gated on unit tests + build_image) plus .circleci/scripts/publish-helm-chart.sh. The script reads the chart version from charts/model-engine/Chart.yaml and only packages + pushes when that tag is not already in public ECR, so it is safe to run on every merge - an actual publish happens only when the chart version was bumped. Replaces the manual on-call helm push. Requires the ecr-public grant on the circleci OIDC role (Terracode-ML). Co-Authored-By: Claude Opus 4.8 --- .circleci/config.yml | 26 +++++++++++++++ .circleci/scripts/publish-helm-chart.sh | 43 +++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100755 .circleci/scripts/publish-helm-chart.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 3a47cf1a..e2f7307f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,8 +16,34 @@ workflows: branches: only: - main + - publish_helm_chart: + requires: + - run_unit_tests_python_client + - run_unit_tests_server + - build_image + filters: + branches: + only: + - main jobs: + publish_helm_chart: + docker: + - image: cimg/aws:2023.09 + resource_class: small + steps: + - checkout + - aws-cli/setup: + role-arn: ${CIRCLECI_ROLE_ARN} + aws-region: AWS_REGION + - run: + name: Install helm + command: | + curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + - run: + name: Publish model-engine Helm chart to public ECR (idempotent) + command: | + ./.circleci/scripts/publish-helm-chart.sh run_unit_tests_python_client: docker: - image: python:3.13-bookworm diff --git a/.circleci/scripts/publish-helm-chart.sh b/.circleci/scripts/publish-helm-chart.sh new file mode 100755 index 00000000..e2900315 --- /dev/null +++ b/.circleci/scripts/publish-helm-chart.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# Publish the model-engine Helm chart to the public ECR registry. +# +# Idempotent: reads the chart version from charts/model-engine/Chart.yaml and +# only packages + pushes when that version tag is not already published. So it +# is safe to run on every merge to main — an actual publish happens only when +# the chart version was bumped. +# +# Requires: helm, aws-cli, and AWS credentials for a principal in account +# 692474966980 with ecr-public publish permission on +# model-engine-helm-charts/model-engine (the CircleCI `circleci` OIDC role). +set -euo pipefail + +CHART_DIR="charts/model-engine" +PUBLIC_ECR_REGISTRY="public.ecr.aws/b2z8n5q1" +CHART_REPO_PATH="model-engine-helm-charts" # helm appends the chart name (model-engine) +ECR_REPOSITORY_NAME="model-engine-helm-charts/model-engine" +ECR_PUBLIC_REGION="us-east-1" # ECR Public API only exists in us-east-1 + +VERSION="$(helm show chart "${CHART_DIR}" | awk '/^version:/ {print $2}')" +if [[ -z "${VERSION}" ]]; then + echo "ERROR: could not determine chart version from ${CHART_DIR}/Chart.yaml" >&2 + exit 1 +fi +echo "model-engine chart version: ${VERSION}" + +if aws ecr-public describe-images \ + --region "${ECR_PUBLIC_REGION}" \ + --repository-name "${ECR_REPOSITORY_NAME}" \ + --image-ids imageTag="${VERSION}" >/dev/null 2>&1; then + echo "Chart ${VERSION} is already published to ${PUBLIC_ECR_REGISTRY}/${ECR_REPOSITORY_NAME} — nothing to do." + exit 0 +fi + +echo "Publishing model-engine chart ${VERSION}..." +aws ecr-public get-login-password --region "${ECR_PUBLIC_REGION}" \ + | helm registry login --username AWS --password-stdin public.ecr.aws + +PKG_DIR="$(mktemp -d)" +helm package "${CHART_DIR}" -d "${PKG_DIR}" +helm push "${PKG_DIR}/model-engine-${VERSION}.tgz" "oci://${PUBLIC_ECR_REGISTRY}/${CHART_REPO_PATH}" + +echo "Published oci://${PUBLIC_ECR_REGISTRY}/${ECR_REPOSITORY_NAME}:${VERSION}"